简体   繁体   English

自定义 JComboBox 编辑器

[英]Custom JComboBox editor

i got stuck at adding a button to a JComboBox editor, I succeeded to add a button but I got some issues like when I first enter to the editor an action perform event gets fired which is unacceptable and the other is I can't get the text typed.我在向JComboBox编辑器添加按钮时遇到JComboBox ,我成功添加了一个按钮,但遇到了一些问题,例如当我第一次进入编辑器时,触发了一个不可接受的操作执行事件,另一个是我无法获得输入的文本。

Result:结果:结果

Problems:问题:

问题

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

This is the problem, if I return panel.jtexfield I only get a text field without a button, so what's the trick here?这就是问题所在,如果我返回panel.jtexfield我只会得到一个没有按钮的文本字段,那么这里有什么技巧呢?

Here is my code这是我的代码

    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. 
*/  

    }  
}  

I also wish to set the text font and size to the same as the set up at the combo box.我还希望将文本字体和大小设置为与组合框中的设置相同。

The first set of problems I can see is, you define a JTextField and JButton in the NewComboEditor , but also define a textPanel , which contains all these things any way.我能看到的第一组问题是,您在NewComboEditor定义了JTextFieldJButton ,但也定义了textPanel ,它以任何方式包含所有这些东西。 But instead of using the components on the textPane , you use the newly created components (in the NewComboEditor ) instead...In fact, I'm not even sure how that could work, because you never initilise these components (in the NewComboEditor ), so there should be a NullPointerException ...但是,您没有使用textPane上的textPane ,而是使用新创建的组件(在NewComboEditor )……事实上,我什至不确定这如何工作,因为您从未初始化这些组件(在NewComboEditor ) ,所以应该有一个NullPointerException ...

If that wasn't enough problems, the JTextField and JButton aren't added to anything anyway...如果这还不够,那么JTextFieldJButton不会被添加到任何东西中......

Instead...反而...

  • NewComboEditor shouldn't need to extend from anything (or it could extend from textPane instead if you really wanted to). NewComboEditor不需要从任何东西扩展(或者如果你真的想要,它可以从textPane扩展)。
  • All references to the field should be made to the text field in the textPane对该字段的所有引用都应textPane的文本字段

As an example...举个例子...

在此处输入图片说明

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);
        }
        
    }
    
}

Now, if you want to set the field's properties to be the same as the combo box, I would simply pass a reference of the combo box to the editor and allow it to extract the properties you need (ie font, color, etc.)现在,如果您想将字段的属性设置为与组合框相同,我只需将组合框的引用传递给编辑器并允许它提取您需要的属性(即字体、颜色等)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM