首页 > 解决方案 > JTable中的JComboBox不保存选择

问题描述

我有一个包含一个NameChoice列的 JTable。我希望该Choice列包含一个JComboBox对每一行都有相同选择的组件,尽管允许对每个唯一行进行独立选择。

目前,与JComboBox列内的交互允许出现下拉菜单以进行选择;但是,没有保存任何选择。

在此处输入图像描述

相反,所做的选择会迁移到JComboBox我点击的任何地方。例如,我单击第一行JComboBox并选择“Choice B”,但所有选项仍显示为“Choice A”。直到我单击另一行时JComboBox,才会出现下拉菜单,并突出显示“Choice B”选项。

该表使用的代码如下:

final String[] choices = new String[]{"Choice A", "Choice B", "Choice C"};
final Collection<String> mockData = Arrays.asList("First", "Second", "Third", "Fourth", "Fifth", "Sixth");
table.setModel(new MasterTableModel(mockData.stream().map(s -> {
    return new Object[]{s, new JComboBox<>(choices)};
}).collect(Collectors.toSet())));
table.setDefaultEditor(JComboBox.class, new DefaultCellEditor(new JComboBox<>(choices)));
table.setDefaultRenderer(JComboBox.class, new MasterTableComboRenderer(table.getDefaultRenderer(JComboBox.class)));

我有三个选择,用于初始化JComboBox填充Choice列的 es。我将 设置为实现接口DefaultRenderer的自定义MasterTableComboRenderer对象,TableCellRenderer以便JComboBox显示为 aComponent而不是打印对象的地址。它只需要覆盖一个方法:

class MasterTableComboRenderer ...
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
    return value instanceof Component ? (Component) value : renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}

最后,MasterTableModel是 的简单扩展AbstractTableModel,它定义了列标题[Name, Choice]并保存了Object[][]代表JTable的数据。我已经覆盖isCellEditablegetColumnClass如下:

class MasterTableModel...
@Override
public boolean isCellEditable(final int rowIndex, final int columnIndex) {
    return getColumnName(columnIndex).equals("Choice");
}

@Override
public Class<?> getColumnClass(final int columnIndex) {
    return getValueAt(0, columnIndex).getClass();
}

JComboBox为了实现保存其选择的功能并且没有将选择突出显示迁移到其他框,我是否缺少一些东西?

标签: javaswing

解决方案


AJComboBox不应该存储在TableModel. 该String值存储在模型中。

阅读 Swing 教程中关于使用组合框作为渲染器的部分以获取工作示例。

如果您希望渲染器看起来像一个组合框,那么您需要使用组合框作为渲染器。就像是:

class ComboBoxRenderer extends JComboBox implements TableCellRenderer
{
    public ComboBoxRenderer()
    {
        setBorder(null);
    }

    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        removeAllItems();
        addItem( value );

        return this;
    }
}

推荐阅读