JComboBox中的空值停止箭头键使用

时间:2023-01-27 23:07:14

The code below has a bug. Upon loading the JFrame, press tab to focus on the JComboBox, and try pressing the down key. It doesn't do anything.

下面的代码有一个错误。加载JFrame后,按Tab键聚焦JComboBox,然后尝试按下向下键。它没有做任何事情。

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.

在位置0处插入Null会导致这种情况。但是,我仍然希望能够选择Null。我不想强迫用户选择一个选项。

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?

我可以在JComboBox中覆盖一些东西来修复这种行为吗?

I don't really fancy inserting an empty String at position 0 as I'll have to deal with that everywhere.

我真的不想在0号位置插入一个空字符串,因为我必须在任何地方处理它。

Using a Wrapping object may be an option, but I'd rather extend and then override something in JComboBox.

使用Wrapping对象可能是一个选项,但我宁愿扩展然后覆盖JComboBox中的某些东西。

2 个解决方案

#1


2  

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.

空对象在JComboBox中不能很好地播放。例如,组合框的getSelectedIndex方法(在选择项时触发)将返回-1(如果对象为null)。可能还有其他方法执行空检查并可能返回不正确的结果。

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:

但您可以尝试重写getSelectedIndex,以便在对象为null时返回0而不是-1。还要覆盖selectedItemChanged,以便它不检查空值。以下似乎有效,但可能还有其他方法需要重写:

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); 

#2


1  

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.

以这种方式创建组合框会创建基于Vector的DefaultComboBoxModel。因此无法插入空值。您可以尝试使用nulls支持实现ComboBoxModel。

#1


2  

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.

空对象在JComboBox中不能很好地播放。例如,组合框的getSelectedIndex方法(在选择项时触发)将返回-1(如果对象为null)。可能还有其他方法执行空检查并可能返回不正确的结果。

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:

但您可以尝试重写getSelectedIndex,以便在对象为null时返回0而不是-1。还要覆盖selectedItemChanged,以便它不检查空值。以下似乎有效,但可能还有其他方法需要重写:

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); 

#2


1  

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.

以这种方式创建组合框会创建基于Vector的DefaultComboBoxModel。因此无法插入空值。您可以尝试使用nulls支持实现ComboBoxModel。