Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

Result: result

Problems:

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?

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.

like image 876
GoAntonio Avatar asked Jan 17 '26 16:01

GoAntonio


1 Answers

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

If that wasn't enough problems, the JTextField and JButton aren't added to anything anyway...

Instead...

  • NewComboEditor shouldn't need to extend from anything (or it could extend from textPane instead if you really wanted to).
  • All references to the field should be made to the text field in the textPane

As an example...

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

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 (i.e. font, color, etc.)

like image 59
MadProgrammer Avatar answered Jan 20 '26 06:01

MadProgrammer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!