Problems with BasicComboBoxEditor
--=-=-=
hi,
I am using an editable ComboBox with BasicComboBoxEditor
(minimal example attached) with GTK or Nimbus L&Fs:
JComboBox comboBox = new JComboBox();
comboBox.setEditable(true);
comboBox.setEditor(new BasicComboBoxEditor());
I am having two problems with this:
#1. the first character in the editable combobox (which uses a
JTextField internally) cannot show the first letter completely (too
few left padding, see attached minimal example)
#2. The Background color of the editable combo box is white
(as opposed to normal comboboxes, which are grey, depending on L&F)
#1 can be worked around by using a MetalComboBoxEditor (without using
metal L&F) instead of the BasicComboBoxEditor. I think this solution
is satisfactory, but does there happen to be a better solution?
#2: Concerning the background color issue, I managed to change the
background color of the JTextField:
class ComboBoxEditorWithBGColor extends MetalComboBoxEditor
{
public ComboBoxEditorWithBGColor()
{
// change the background color of the editor component that the
// ComboBoxEditor uses for editing
Color c = UIManager.getLookAndFeelDefaults().getColor("ComboBox.background");
editor.setBackground(new Color(c.getRed(), c.getGreen(), c.getBlue()));
}
}
....but not the background color of the combobox items that appear
when you "unfold" the combobox. I tried to set a simple renderer:
class SimpleListCellRenderer implements ListCellRenderer
{
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel(value.toString());
label.setBackground(Color.RED);
label.setOpaque(true);
return label;
}
}
.... but this seems to be ignored in the editable combobox.
A workaround is to subclass MetalBasicComboBoxUI:
class MyBasicComboBoxUI extends MetalBasicComboBoxUI
{
public MyBasicComboBoxUI()
{
}
public void setBG()
{
Color c = UIManager.getLookAndFeelDefaults().getColor("ComboBox.background");
listBox.setBackground(new Color(c.getRed(), c.getGreen(), c.getBlue()));
}
}
and set it on the combo:
MyBasicComboBoxUI ui = new MyBasicComboBoxUI();
comboBox.setUI(ui);
ui.setBG();
=> this works, but (of course) the combo box is rendered according to
metal L&F which does not fit in particularly well with non-metal L&F
(and the whole point of this hack is to make editable combo boxes look like
normal ones).
I also tried to use BasicComboBoxUI instead of MetalBasicComboBoxUI, but
then the handle is not drawn at all.
Thanks in Advance and Best Regards!
--
Felix Natter
--=-=-=
Content-Type: text/x-java
Content-Disposition: inline; filename=TestComboBox.java
import javax.swing.*;
import java.awt.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
class MyBasicComboBoxUI extends MetalComboBoxUI
{
public MyBasicComboBoxUI()
{
}
public void setBG()
{
Color c = UIManager.getLookAndFeelDefaults().getColor("ComboBox.background");
listBox.setBackground(new Color(c.getRed(), c.getGreen(), c.getBlue()));
}
}
class ComboBoxEditorWithBGColor extends MetalComboBoxEditor
{
public ComboBoxEditorWithBGColor()
{
Color c = UIManager.getLookAndFeelDefaults().getColor("ComboBox.background");
editor.setBackground(new Color(c.getRed(), c.getGreen(), c.getBlue()));
}
}
class SimpleListCellRenderer implements ListCellRenderer
{
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = new JLabel(value.toString());
label.setBackground(Color.RED);
label.setOpaque(true);
return label;
}
}
public class TestComboBox
{
public static void main(String[] args) throws Exception
{
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JComboBox comboBox = new JComboBox();
comboBox.setEditable(true);
//comboBox.setEditor(new BasicComboBoxEditor());
comboBox.setEditor(new ComboBoxEditorWithBGColor());
//comboBox.setEditor(new MetalComboBoxEditor());
//comboBox.setRenderer(new SimpleListCellRenderer());
MyBasicComboBoxUI ui = new MyBasicComboBoxUI();
comboBox.setUI(ui);
ui.setBG();
panel.add(new JButton("foo"));
panel.add(comboBox);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
--=-=-=--