自定义JComboBox编辑器

时间:2013-07-26 22:54:09

标签: java swing jcombobox

我被困在向JComboBox编辑器添加一个按钮时,我成功添加了一个按钮,但是我遇到了一些问题,比如当我第一次进入编辑器时,一个动作执行事件被触发是不可接受的而另一个是我无法输入文字。

结果: result

问题:

problems

    @Override  
        public Component getEditorComponent() {  
            return panel;  
        }  

这是问题,如果我返回panel.jtexfield我只得到一个没有按钮的文本字段,那么这里的诀窍是什么?

这是我的代码

    import Store.util.DatabaseHelper;  
import java.awt.*;  
import java.awt.event.*;  
import java.util.ArrayList;  
import javax.swing.*;  
import javax.swing.border.Border;  
import javax.swing.plaf.basic.BasicComboBoxEditor;  
import org.hibernate.HibernateException;  
import org.netbeans.lib.awtextra.AbsoluteLayout;  

public class NewComboTest extends JFrame {  

    private ArrayList<Object> shopCart = new ArrayList<Object>();  
    private JComboBox cb;  
    private static final Object[] comboContents = {  
        "First", "Second", "Third", "Fourth", "Fifth"  
    };  

    public NewComboTest() {  

        super("New Combo Test");  
        setLayout(null);  
        cb = new JComboBox();  
        cb.setRenderer(new NewComboRenderer());  

        cb.setEditor(new NewComboEditor());  
        cb.setEditable(true);  

        cb.setSize(new Dimension(350, 100));  
        for (int i = 0; i < comboContents.length; i++) {  
            cb.addItem(comboContents[ i]);  
        }  
        cb.addActionListener(new ActionListener() {  
            @Override  
            public void actionPerformed(ActionEvent e) {  
                System.out.println("_____________" + cb.getSelectedItem());  

                shopCart.add(cb.getSelectedItem());  
                System.out.println("items added" + shopCart);  
            }  
        });  
        cb.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {  
            @Override  
            public void keyReleased(KeyEvent e) {  
                System.out.println("KeyReleased" + cb.getEditor().getItem().toString());  
                populateModel(cb.getEditor().getItem().toString());  
            }  
        });  

        getContentPane().add(cb, new org.netbeans.lib.awtextra.AbsoluteConstraints(320, 200, 480, 50));  
        setSize(1200, 450);  
        setDefaultCloseOperation(EXIT_ON_CLOSE);  
        setVisible(true);  
    }  

    public static void main(String[] arg) {  
        new NewComboTest();  
    }  

    private class NewComboEditor extends JPanel implements ComboBoxEditor {  

        JTextField tf;  
        JButton eraseButton;  
        textPanel panel = new textPanel();  

        public NewComboEditor() {  

        }  

        @Override  
        public void addActionListener(ActionListener l) {  
            tf.addActionListener(l);  
        }  

        @Override  
        public Component getEditorComponent() {  
            return panel;  
        }  
        public Component getEditorComponent2() {  
            return panel;  
        }  

        @Override  
        public Object getItem() {  
            return tf.getText();  

        }  

        @Override  
        public void removeActionListener(ActionListener l) {  
            tf.removeActionListener(l);  
        }  

        @Override  
        public void selectAll() {  
            tf.selectAll();  
        }  

        @Override  
        public void setItem(Object o) {  
            if (o != null) {  
                tf.setText(tf.getText());  
            } else {  
                tf.setText("");  
            }  
        }  

        private class textPanel extends JPanel {  

            JTextField jTextField1 = new JTextField();  
            JButton jButton1 = new JButton();  

            public textPanel() {  
                setLayout(new BorderLayout());  

                jButton1.setBackground(new java.awt.Color(255, 255, 255));  
                jButton1.setForeground(new java.awt.Color(0, 51, 51));  
                jButton1.setText("X");  
                jButton1.addActionListener(new ActionListener() {  
                    @Override  
                    public void actionPerformed(ActionEvent e) {  
                        jTextField1.setText("");  
                    }  
                });  

                add(jTextField1, BorderLayout.CENTER);  
                add(jButton1, BorderLayout.EAST);  





            }  

            public String getText(){  
                return jTextField1.getText();  
            }  
        }  
    }  

    private class NewComboRenderer extends JLabel implements ListCellRenderer {  

        public NewComboRenderer() {  
            setOpaque(true);  
        }  

        public Component getListCellRendererComponent(  
                JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {  
            setText(value.toString());  

            setBackground(isSelected ? Color.BLUE : Color.white);  
            setForeground(isSelected ? Color.white : Color.red);  
            return this;  
        }  
    }  

   /* public void populateModel(String text) throws HibernateException { 
        java.util.List l = DatabaseHelper.GetProductsBy(text); 

        for (Object object : l) { 
            cb.addItem(object); 
        } 
ignore this its unnecessary. 
*/  

    }  
}  

我还希望将文本字体和大小设置为与组合框中的设置相同。

1 个答案:

答案 0 :(得分:6)

我可以看到的第一组问题是,您在JTextField中定义了JButtonNewComboEditor,还定义了textPanel,其中包含所有这些内容无论如何。但是,不是使用textPane上的组件,而是使用新创建的组件(在NewComboEditor中)而不是......事实上,我甚至不确定这是如何工作的,因为你永远不会初始化这些组件(在NewComboEditor中),因此应该有NullPointerException ...

如果问题不够,JTextFieldJButton不会被添加到任何内容中......

,而不是...

  • NewComboEditor不需要从任何内容扩展(或者如果您真的想要,可以从textPane扩展。)
  • 该字段的所有引用都应该在textPane
  • 的文本字段中进行

作为一个例子......

enter image description here

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.ComboBoxEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class CustomComboBoxEditor {

    public static void main(String[] args) {
        new CustomComboBoxEditor();
    }

    public CustomComboBoxEditor() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JComboBox cb = new JComboBox();
                cb.addItem("Apple");
                cb.addItem("Banana");
                cb.addItem("Orange");
                cb.setEditable(true);
                cb.setEditor(new MyComboBoxEditor());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(cb);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyComboBoxEditor implements ComboBoxEditor {

        private EditorPane editorPane;

        public MyComboBoxEditor() {
            editorPane = new EditorPane();
        }

        @Override
        public Component getEditorComponent() {
            return editorPane;
        }

        @Override
        public void setItem(Object anObject) {
            editorPane.setText(anObject == null ? null : anObject.toString());
        }

        @Override
        public Object getItem() {
            return editorPane.getText();
        }

        @Override
        public void selectAll() {
            editorPane.selectAll();
        }

        @Override
        public void addActionListener(ActionListener l) {
            editorPane.addActionListener(l);
        }

        @Override
        public void removeActionListener(ActionListener l) {
            editorPane.removeActionListener(l);
        }

    }

    public class EditorPane extends JPanel {

        private JTextField field;
        private JButton button;

        public EditorPane() {
            field = new JTextField(10);
            button = new JButton("X");
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridx = 0;
            add(field, gbc);
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.NONE;
            gbc.gridx++;
            add(button, gbc);
        }

        @Override
        public void addNotify() {
            super.addNotify(); 
            field.requestFocusInWindow();
        }

        public void selectAll() {
            field.selectAll();
        }

        public void setText(String text) {
            field.setText(text);
        }

        public String getText() {
            return field.getText();
        }

        public void addActionListener(ActionListener listener) {
            field.addActionListener(listener);
        }

        public void removeActionListener(ActionListener listener) {
            field.removeActionListener(listener);
        }

    }

}

现在,如果你想将fields属性设置为与组合框相同,我只需将组合框的引用传递给编辑器,并允许它提取你需要的属性(即字体,颜色)等等)