简体   繁体   English

选择后,JTable将JComboBox和JCheckBox还原为值

[英]JTable Reverts JComboBox and JCheckBox to Values after Selection

I have a JTable with a column of JComboBox<Integer> s and a column of JCheckBox s. 我有一个JTable,其中有一列JComboBox<Integer>和一列JCheckBox The JTable is set with the appropriate renderers and editors. 使用适当的渲染器和编辑器设置JTable。 The table looks fine at first, but after selecting a value from the combobox or checkbox, the cells seem to revert to the values of Integer and Boolean. 该表最初看起来不错,但是从组合框或复选框中选择了一个值之后,单元格似乎恢复为Integer和Boolean的值。 The issue appears to be more than cosmetic, as methods that anticipate the cell having a combobox or a checkbox throw errors at finding an Integer or a Boolean. 这个问题似乎不仅仅是表面上的问题,因为预期具有组合框或复选框的单元格的方法会在查找整数或布尔值时引发错误。

Here is a picture of what it looks like: 这是它的外观图:

在此处输入图片说明

And here is the code: 这是代码:

    dataTable.removeAll();
    numberOfVariables = 7;
    Object[] header = new Object[numberOfVariables];
    header[0] = new String("Ring Number");
    header[1] = new String("Radius (cm)");
    header[2] = new String("Plume Distribution");
    header[3] = new String("Thickness (A)");
    header[4] = new String("Deposition Time (s)");
    header[5] = new String("Rate (A/s)");
    header[6] = new String("Optimize (y/n)");

    Object[][] data = new Object[numberOfRings][numberOfVariables];
    for(int k=0;k<numberOfRings;++k){
        Object[] row = new Object[numberOfVariables];
        row[0] = Integer.toString(k+1);
        row[1] = String.format("%.2f", plume.getRingRadius(k));
        row[2] = createDistributionComboBoxForRing(k);
        row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
        row[4] = String.format("%.2f", plume.getTimeForRing(k));
        row[5] = String.format("%.2f", plume.getRateForRing(k));
        row[6] = new JCheckBox();
        ((JCheckBox) row[6]).setSelected(true);
        data[k] = row;
    }
    tableModel = new DefaultTableModel(data,header);
    dataTable.setModel(tableModel);
    dataTable.getColumnModel().getColumn(2).setCellRenderer(new ControlTableRenderer());
    //dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( createDistributionComboBoxForRing(0) ));
    dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( (JComboBox<Integer>) data[0][2] ));
    dataTable.getColumnModel().getColumn(6).setCellRenderer(new ControlTableRenderer());
    dataTable.getColumnModel().getColumn(6).setCellEditor(new DefaultCellEditor( (JCheckBox) data[0][6] ));
    dataTable.updateUI();
row[2] = createDistributionComboBoxForRing(k);
row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
row[4] = String.format("%.2f", plume.getTimeForRing(k));
row[5] = String.format("%.2f", plume.getRateForRing(k));
row[6] = new JCheckBox();
((JCheckBox) row[6]).setSelected(true);

The TableModel for a JTable stores data, not components. JTable的TableModel存储数据,而不存储组件。

So if column 3 contains an Integer object then you store an Integer in the TableModel and you set the editor for the column to be a combo box containing the list of valid Integers. 因此,如果列3包含一个Integer对象,则将一个Integer存储在TableModel ,并将该列的编辑器设置为包含有效Integer列表的组合框。

Same for the column containing the check box renderer/editor. 与包含复选框渲染器/编辑器的列相同。 In this case you store a Boolean object. 在这种情况下,您将存储一个Boolean对象。

For example: 例如:

row[2] = new Integer(1);
row[6] = Boolean.TRUE

Now in the TableModel you need to tell the table what type of data is in each column so you need to override the getColumnClass(...) method. 现在,在TableModel中,您需要告诉表每一列中的数据类型,因此您需要重写getColumnClass(...)方法。 Something like: 就像是:

tableModel = new DefaultTableModel(data,header)
{
    @Override
    public Class getColumnClass(int column)
    {
        switch (column)
        {
            case 2: return Integer.class;
            case 6: return Boolean.class;
            default: return Object.class;
        }
    }
};

Now the table can choose the appropriate renderer and editor for each column. 现在,表格可以为每列选择适当的渲染器和编辑器。

However, in the case of the combo box you do have to create a custom editor with the values for the combo box. 但是,对于组合框,必须使用组合框的值创建一个自定义编辑器。 See the section from the Swing tutorial on Using a Combo Box as an Editor for a working example on how to do this. 有关如何执行此操作的工作示例,请参见Swing教程中有关使用组合框作为编辑器的部分。

Also, you are incorrectly using some other methods: 另外,您错误地使用了其他一些方法:

dataTable.removeAll();

Not sure what that is for. 不知道那是为了什么。 That is a Container method to remove components from the panel. 这是一种从面板上删除组件的Container方法。 All you need is the setModel(...) statement to reset the table. 您需要做的就是setModel(...)语句以重置表。

dataTable.updateUI();

There is no need to use the updateUI() method. 无需使用updateUI()方法。 That method is used internally when the LAF is changed. 更改LAF时在内部使用该方法。 You are not changing the LAF so get rid of that statement. 您没有更改LAF,因此请摆脱该声明。

The idea of cell renderers and editors is that you only have one component and that gets moved around and data changed for each row. 单元格渲染器和编辑器的想法是,您只有一个组件,并且四处移动并且每行更改数据。 The code uses a different JComponent instance for each cell. 该代码为每个单元使用一个不同的JComponent实例。 Just put the data in the table model and let the cell renderer and editors manage the components. 只需将数据放入表模型中,然后让单元格渲染器和编辑器管理组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM