I am using Metal L&F. I want to make a JComboBox, that has only 1 pixel border. This not a problem, as long as the cb is editable. This corresponds to the first cb in the picture named "Editable".
cb.setEditable(true);
((JTextComponent) (cb.getEditor().getEditorComponent())).setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR));
But when I do cb.setEditable(false), an additional border occurs inside the box (changed to red in the picture "Dropdown", you see the original color in the picture named "Fixed"). Although I tried to set the border and I also tried to use my own CellRenderer, the border still gets painted. It seems to me, that the unwanted border does not come from the CellRenderer. When I try to manipulate the border from the cb itself (see comment //), it only adds/removes an additional outer border. The editorComponent also seems not to be responsible to me.
cb.setRenderer(new CbCellRenderer());
//cb.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, COLOR));
//cb.setBorder(BorderFactory.createEmptyBorder());
class CbCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
renderer.setBorder(BorderFactory.createEmptyBorder());
return renderer;
}
}
I also tried out some UI variables like the ones below without taking affect on this border.
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
UIManager.put("ComboBox.selectionForeground", Color.green);
UIManager.put("ComboBox.disabledBackground", Color.green);
...
Image: http://upload.mtmayr.com/dropdown_frame.png (link broken)
Complete code for testing:
import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboPopup;
public class ComboTest {
private Vector<String> listSomeString = new Vector<String>();
private JComboBox editableComboBox = new JComboBox(listSomeString);
private JComboBox nonEditableComboBox = new JComboBox(listSomeString);
private JFrame frame;
public final static Color COLOR_BORDER = new Color(122, 138, 153);
public ComboTest() {
listSomeString.add("row 1");
listSomeString.add("row 2");
listSomeString.add("row 3");
listSomeString.add("row 4");
editableComboBox.setEditable(true);
editableComboBox.setBackground(Color.white);
Object child = editableComboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup) child;
JList list = popup.getList();
list.setBackground(Color.white);
list.setSelectionBackground(Color.red);
JTextField tf = ((JTextField) editableComboBox.getEditor().getEditorComponent());
tf.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, COLOR_BORDER));
nonEditableComboBox.setEditable(false);
nonEditableComboBox.setBorder(BorderFactory.createEmptyBorder());
nonEditableComboBox.setBackground(Color.white);
Object childNonEditable = nonEditableComboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popupNonEditable = (BasicComboPopup) childNonEditable;
JList listNonEditable = popupNonEditable.getList();
listNonEditable.setBackground(Color.white);
listNonEditable.setSelectionBackground(Color.red);
frame = new JFrame();
frame.setLayout(new GridLayout(0, 1, 10, 10));
frame.add(editableComboBox);
frame.add(nonEditableComboBox);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ComboTest ct = new ComboTest();
}
});
}
}