I want to modify the display of a (non-editable) JComboBox
in such a fashion that the currently selected entry has some extra text in the edit field (not the dropdown list, though).
Something like this:
My first guess was to override the ComboBox’ model so that getSelectedItem
returns a wrapper object modifying the display:
petList.setModel(new ComboBoxModel() {
private Object selected;
public void setSelectedItem(Object anItem) {
selected = anItem;
}
public Object getSelectedItem() {
return new ActiveComboItem(selected);
}
// … The rest of the methods are straightforward.
});
Where ActiveComboItem
looks as follows:
static class ActiveComboItem {
private final Object item;
public ActiveComboItem(Object item) { this.item = item; }
@Override
public boolean equals(Object other) {
return item == null ? other == null : item.equals(other);
}
@Override
public String toString() { return String.format("Animal: %s", item); }
}
Indeed, this works as far as modifying the display goes. Unfortunately, the current entry is no longer marked as active:
(Note the missing check mark … or however the selection is displayed by your OS.)
Further inspection shows that the model’s getElementAt
method is called with an index of -1
every time the user selects a new item in the box. This is only the case when using the modified selected item. When the model’s getSelectedItem
method returns the plain object without wrapper, then the selected item is marked as selected in the dropdown box, and getElementAt
is not called with an argument of -1
.
Apparently, the ComboBox is comparing each item in turn to the currently active item but, despite my overriding the equals
method, it finds no match. How can I fix this?
(Full, compilable code for this problem at gist.github.com)