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

时间:2011-01-21 10:52:38

标签: java swing jcombobox

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

在位置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();
    }
}

我是否可以在JComboBox中覆盖以修复此行为?

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

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

2 个答案:

答案 0 :(得分:2)

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

但您可以尝试覆盖getSelectedIndex,以便在对象为空时返回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));
    }
};

但是,我建议使用包装器对象,而不是执行上述操作。例如:

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

答案 1 :(得分:1)

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