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

Java JTable JComboBox默认在列表展开时显示第一项,java,swing,jtable,jcombobox,jlist,Java,Swing,Jtable,Jcombobox,Jlist,我一直在试图确定为什么我的JComboBox会通过大量谷歌搜索显示列表中的第一项,但我正在努力寻找相关帮助。可能是因为我不知道正确的术语(因此这个问题的标题过于具体),因此没有找到能够解释我的问题的信息。我查看了JComboBox API,以及它使用的一些侦听器和模型,但它们似乎不太可能是候选对象 所讨论的JComboBox位于JTable中,因此我不知道这是否会改变它的默认行为。我使用的代码如下所示: //row and col are final due to usage inside an

我一直在试图确定为什么我的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);
}
//由于在匿名内部类中使用,所以行和列是最终的
公共表格CellEditor getCellEditor(最终整数行,最终整数列)
{
String[]listItems=新字符串[arrayList.getSize()];
int i=-1;
for(字符串s:arrayList)
{
i++;
列表项[i]=s;
}
JComboBox=新的JComboBox(列表项);
addItemListener(新的ItemListener()
{
公共无效itemStateChanged(ItemEvent e)
{
如果(如getStateChange()==ItemEvent.SELECTED)
{
如果(e.getItem().equals(“添加/编辑项目”))
{
//其中编辑器是将打开的JFrame
新编辑();
}
}
}
});
DefaultCellEditor列表=新建DefaultCellEditor(框);
}
请注意,我的程序中的Arraylist不包含字符串,而是一组更复杂的自定义对象,我认为这会分散对主要问题的注意力

我没有在JTable中包含JComboBox的渲染器,因为我对它的显示方式非常满意,并且认为我的问题更多的是我忽略了在模型中实现/实现错误

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

第二个图像是我刚刚单击JComboBox以显示列表的时候。如图所示,它将立即显示第一项,无论它是什么。

如果有人对在哪里寻找/解决方案有任何建议,我将不胜感激


编辑

我的特定表有两列,其中左列是变量名,右列是与变量关联的值。tables角色是显示选定对象的属性,其中不同对象的不同变量的每个值可能不相同

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

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


唯一的问题是,当列表展开时,它总是选择列表中的第一项。

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

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

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

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

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

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

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

//...
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(值)的使用,这会将选定值设置为单元格当前值


您还可以重新使用该模型,每次都将其清除并用新值重新填充。如果您有大量的行,您可能会发现这更有效,因为您不需要每次编辑单元格时都不断创建新模型,除非为每行动态生成
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(值)的使用,这会将选定值设置为单元格当前值


您还可以重新使用该模型,每次都将其清除并用新值重新填充。如果您有大量的行,您可能会发现这更有效,因为您不需要每次编辑单元格时都不断创建新模型,除非为每行动态生成
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(值)的使用,这会将选定值设置为单元格当前值

您还可以重新使用该模型,每次清除它并重新填充i