The code below has a bug. Upon loading the JFrame, press tab to focus on the JComboBox, and try pressing the 开发者_C百科down key. It doesn't do anything.
Inserting Null at position 0 causes this. However, I would still like to be able to select Null. I don't want to force the user to pick an option.
package kobalt.test.colin;
import java.awt.*;
import javax.swing.*;
public class ColinTest extends JFrame {
private JTextField mTextField;
private JComboBox mComboBox;
public ColinTest(){
setLayout(new BorderLayout());
mTextField = new JTextField("Something");
mComboBox = new JComboBox(new String[]{"One", "Two"});
mComboBox.insertItemAt(null, 0); //this line causes the bug
add(mTextField, "North");
add(mComboBox, "South");
pack();
setVisible(true);
}
public static void main(String[] argv) {
new ColinTest();
}
}
Is there something I can override in JComboBox to fix this behaviour?
I don't really fancy inserting an empty String at position 0 as I'll have to deal with that everywhere.
Using a Wrapping object may be an option, but I'd rather extend and then override something in JComboBox.
Null objects do not play nicely in a JComboBox. For example, the combo box's getSelectedIndex
method, which is fired when you select an item, will return -1 if the object is null
. There may also be other methods which perform null checks and may return incorrect results.
But you can try overriding the getSelectedIndex
so that it returns 0 instead of -1 if the object is null. Also override selectedItemChanged
so that it doesn't check for nulls. The following seems to work, but there may be other methods which need to be overridden too:
JComboBox mComboBox = new JComboBox(new String[]{"One", "Two"}){
@Override
public int getSelectedIndex() {
Object sObject = dataModel.getSelectedItem();
int i,c;
Object obj;
if(sObject==null){
return 0;
}
for ( i=0,c=dataModel.getSize();i<c;i++ ) {
obj = dataModel.getElementAt(i);
if ( obj != null && obj.equals(sObject) )
return i;
}
return -1;
}
@Override
protected void selectedItemChanged() {
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
selectedItemReminder,
ItemEvent.DESELECTED));
selectedItemReminder = dataModel.getSelectedItem();
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
selectedItemReminder,
ItemEvent.SELECTED));
}
};
However, instead of doing the above, I would recommend using a wrapper object. For example:
class StringWrapper{
final String s;
public StringWrapper(String s){
this.s=s;
}
@Override
public String toString() {
return s;
}
}
JComboBox cb = new JComboBox(new StringWrapper[]{
new StringWrapper("one"),
new StringWrapper("two"),
new StringWrapper("three")});
cb.insertItemAt(new StringWrapper(null), 0);
Creation of combobox in such a way creates DefaultComboBoxModel which is based on Vector. So nulls can't be inserted. You can try to implement your ComboBoxModel with nulls support.
精彩评论