In my last post I spoke about a JCombobox with the ability to add disabled items. Today I muse a little more on the JCombobox. This time I wanted to add an item to the JCombobox that is not part of the list with displayed items.

JCombobox has a method setSelectedItem(Object anObject) for this. When you call this method with an item that is not part of the list it will only be displayed when the JCombobox is editable, if the JCombobox is not editable it will be ignored completely. So, in order to get an JCombobox to which we can call setSelectedItem(Object anObject) with the provided Object not being part of the list and that is not editable we extend our previous DisabledItemsCombobox with our own ComboBoxEditor. Now the trick is that we set the JCombobox editable property to true, but the editable property of the ComboBoxEditor to false.
import java.awt.Component;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class DisabledItemsComboboxDemo extends JFrame {
public static void main(String[] args) {
DisabledItemsComboboxDemo frame = new DisabledItemsComboboxDemo(
"Combobox displaying an item that is not part of the list");
frame.setVisible(true);
}
public DisabledItemsComboboxDemo(String title) {
super(title);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.init();
}
private void init() {
this.setSize(500, 50);
DisabledItemsComboBox box = new DisabledItemsComboBox();
box.addItem("This item is disabled but selected at first appearance", true);
box.addItem("This item is disabled and you cannot select it", true);
box.addItem("This is the first selectable item");
box.addItem("This is the second selectable item");
box.addItem("This is the third selectable item");
MyComboBoxEditor editor = new MyComboBoxEditor();
box.setEditor(editor);
box.setEditable(true);
box.setSelectedItem("This item is not in the list of selectable items");
add(box);
}
private class DisabledItemsComboBox extends JComboBox {
public DisabledItemsComboBox() {
super();
super.setRenderer(new DisabledItemsRenderer());
}
private Set disabled_items = new HashSet();
public void addItem(Object anObject, boolean disabled) {
super.addItem(anObject);
if (disabled) {
disabled_items.add(getItemCount() - 1);
}
}
@Override
public void removeAllItems() {
super.removeAllItems();
disabled_items = new HashSet();
}
@Override
public void removeItemAt(final int anIndex) {
super.removeItemAt(anIndex);
disabled_items.remove(anIndex);
}
@Override
public void removeItem(final Object anObject) {
for (int i = 0; i < getItemCount(); i++) {
if (getItemAt(i) == anObject) {
disabled_items.remove(i);
}
}
super.removeItem(anObject);
}
@Override
public void setSelectedIndex(int index) {
if (!disabled_items.contains(index)) {
super.setSelectedIndex(index);
}
}
private class DisabledItemsRenderer extends BasicComboBoxRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
if (disabled_items.contains(index)) {
setBackground(list.getBackground());
setForeground(UIManager.getColor("Label.disabledForeground"));
}
setFont(list.getFont());
setText((value == null) ? "" : value.toString());
return this;
}
}
}
public class MyComboBoxEditor extends BasicComboBoxEditor {
public MyComboBoxEditor() {
editor.setEditable(false);
}
}
}