JTable JComboBox 默认在展开列表时显示第一项

JTable JComboBox is defaulting to display 1st item when list is expanded

我一直试图通过大量 Google 搜索来确定为什么我的 JComboBox 显示列表中的第一项,但我正在努力寻找相关帮助。可能是我不知道正确的术语(因此这个问题的标题过于具体),因此找不到可以解释我的问题的信息。我检查了 JComboBox API,以及它使用的一些侦听器和模型,但它们似乎不太可能是候选对象。

有问题的 JComboBox 在 JTable 中,所以我不知道这是否会改变它的默认行为。我使用的代码如下:

//row and col are final due to usage inside anonymous inner class
public TableCellEditor getCellEditor(final int row, final int col)
{
    String[] listItems = new String[arrayList.getSize()];
    int i = -1;

    for(String s : arrayList)
    {
        i++;
        listItems[i] = s;
    }

    JComboBox<String> box = new JComboBox<>(listItems);
    box.addItemListener(new ItemListener()
    {
        public void itemStateChanged(ItemEvent e)
        {
            if(e.getStateChange() == ItemEvent.SELECTED)
            {
                if(e.getItem().equals("Add/Edit Projectile"))
                {
                    //Where Editor is a JFrame that will be opened 
                    new Editor();
                }
            }
        }
    });

    DefaultCellEditor list = new DefaultCellEditor(box);
}

请注意,我程序中的 Arraylist 不包含字符串,而是一组更复杂的自定义 object,我认为这会分散主要问题的注意力。

我没有在 JTable 中包含 JComboBox 的渲染器,因为我对它的显示方式很满意,并且认为我的问题更多的是我在 model/implemented错了。

我还提供了一些屏幕截图以更好地描述我的问题。第一个图像是未选择 JComboBox 时,仅显示当前选中的项目。

第二张图片是我刚刚单击 JComboBox 以显示列表时的情况。如图所示,它会立即调出第一个项目,无论它是什么。

如果有人对look/solutions有什么建议,我将不胜感激。


编辑

我的特定 table 有两列,其中左列是变量名,右列是与变量关联的值。 tables 的作用是显示所选 object 的属性,其中不同 objects 的不同变量的每个值可能不相同。

在这种特殊情况下,单元格显示一个 JComboBox,其中包含我们正在制作的游戏中的所有可用射弹。每个敌人都有不同类型的默认射弹。因此,当我在游戏区域中单击不同的敌人时,table 将显示其所有当前属性(如果未更改则为默认值)。

敌人确实有一个 getter 射弹,所以我可以确定当前选择的敌人是什么,获取它的射弹,执行 toString() 以查找它在列表中的表示方式,并执行 setValueAt()。

目前唯一的问题是展开列表时总是选择列表中的第一项。

这是您应该默认为先前选择的元素的方式:

//...
Object selectedItem = box.getSelectedItem();
//Add some elements to the jComboBox
box.setSelectedItem(selectedItem);

除非 JComboBox 的值是为每一行动态生成的,否则您应该能够提前准备好 CellEditor,例如...

JComboBox cb = new JComboBox(new String[]{"1", "2", "3", "4"});
DefaultCellEditor editor = new DefaultCellEditor(cb);

JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);

这将在编辑过程开始时将编辑器的选定值设置为单元格的值

已更新

在每行动态生成组合框值的情况下,您可以做更像...

JComboBox cb = new JComboBox();
DefaultCellEditor editor = new DefaultCellEditor(cb) {

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        JComboBox editor = (JComboBox) getComponent();
        String[] listItems = new String[arrayList.getSize()];
        int i = -1;
        for (String s : arrayList) {
            i++;
            listItems[i] = s;
        }

        DefaultComboBoxModel model = new DefaultComboBoxModel(listItems);
        editor.setModel(model);
        editor.setSelectedItem(value);
        return editor;
    }
};

JTable table = new JTable(new DefaultTableModel(5, 1));
table.getColumnModel().getColumn(0).setCellEditor(editor);

注意 editor.setSelectedItem(value); 的使用,这会将所选值设置为单元格当前值...

您还可以重新使用该模型,每次都清除它并用新值重新填充它。如果您有大量行,您可能会发现这更有效,因为您不需要在每次编辑单元格时都不断地创建新模型

这怎么是老歌...

您的问题很可能是您没有在组合中使用的 class 中实现 "equals"。

Combo 在准备时需要 select 当前项目,并通过迭代模型的元素和 select 第一个等于值的元素来实现细胞。如果遇到 none 则它会按原样保留组合(第一个元素或上一个单元格编辑中最后使用的元素)