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:

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.
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).textPaneAs 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 (i.e. font, color, etc.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With