简体   繁体   English

如何以编程方式更新jtable单元格和TableModel?

[英]How to update jtable cell and TableModel programmatically?

I need to ensure that only one checkbox in column is selected. 我需要确保仅选中列中的一个复选框。 So, when user selects checkbox I must unselect previous selected. 因此,当用户选中复选框时,我必须取消选择先前选择的复选框。

I tried to do it in setValueAt method of TableModel but I cannot update cell, even that one which I click by button. 我尝试在TableModel的setValueAt方法中执行此操作,但是我无法更新单元格,即使单击按钮也无法更新该单元格。 I don't show all my code, instead I created simple sample that should help to try out solutions: 我没有显示我的所有代码,而是创建了一个简单的示例,该示例应有助于尝试解决方案:

public class DateFormatDemo extends JFrame
{
    private JTable dataSearchResultTable;

    public DateFormatDemo()
    {
        JPanel panel = new JPanel(new GridLayout(2, 1, 5, 10));
        panel.setPreferredSize(new Dimension(500, 300));
        dataSearchResultTable = new JTable(new MyTableModel());

        dataSearchResultTable.setSelectionBackground(new Color(0xaaaaff));
        dataSearchResultTable.setFillsViewportHeight(true);
        dataSearchResultTable.setRowSelectionAllowed(true);
        dataSearchResultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        dataSearchResultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        dataSearchResultTable.setRowHeight(25);

        panel.add(new JScrollPane(dataSearchResultTable));
        super.getContentPane().add(panel);
        super.pack();
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setVisible(true);
    }

    class MyTableModel extends AbstractTableModel
    {
        private String[] columnNames = { "First Name", "Last name", "Vegetarian" };
        private Object[][] data;

        MyTableModel()
        {
            data = new Object[][] { { "Vova", "KipokKipokKipokKipok", false }, { "Olia", "Duo", true },
                    { "Ivan", "Brown", false } };
            fireTableDataChanged();
        }

        public int getColumnCount()
        {
            return columnNames.length;
        }

        public int getRowCount()
        {
            return data.length;
        }

        public String getColumnName(int col)
        {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col)
        {
            if (data.length > 0 && data[0] != null) {
                return data[row][col];
            }
            return null;
        }

        public Class getColumnClass(int c)
        {
            Object valueAt = getValueAt(0, c);
            return valueAt == null ? Object.class : valueAt.getClass();
        }

        public boolean isCellEditable(int row, int col)
        {
            return true;
        }

        public void setValueAt(Object value, int row, int col)
        {
            if (data.length > 0 && data[0] != null) {
                data[row][col] = value;
                fireTableCellUpdated(row, col);
            }
        }
    }

    public static void main(String[] args) throws ParseException
    {
        new DateFormatDemo();
    }
}

So, I want Vegeterian column to have only one checkbox selected and when user selects one checkbox then another should become unselected. 因此,我希望Vegeterian列仅选择一个复选框,并且当用户选择一个复选框时,另一个应该变为未选中状态。

Thank you! 谢谢!

A lot will come down to how your model is structured. 很大程度上取决于模型的结构。

Basically, in your setValueAt method, when you determine that the "checkbox" column has been changed, you will need find any value in that column which is (I presume) true and make it false , firing a TableCellUpdated event, indicating that you've changed the cell value. 基本上,在您的setValueAt方法中,当您确定“复选框”列已更改时,您将需要在该列中找到(我认为是) true并将其设置为false任何值,从而触发TableCellUpdated事件,指示您ve更改了单元格的值。

Assuming that only one cell can ever be true , you could break at that point and continue on modifying the cell value as per normal. 假设只有一个单元格可以是true ,那么您可以在此时中断并继续按照常规修改单元格值。

Another, more risky, solution might be to maintain the row index of the last cell that was made true and simply rest it when the value changes... 另一个风险更大的解决方案可能是维护最后一个为真的单元格的行索引,并在值更改时简单地休息它。

The risk here comes from ensuring that when the model is constructed, you know which row is true , that the underlying data follows your rules (and only has one true row) and lack of control over the backing data (maybe not in this example, but in other examples) 这里的风险来自于确保在构建模型时,您知道哪一行是true ,底层数据遵循您的规则(并且只有一个true行),并且缺乏对后备数据的控制(在此示例中可能不是,但在其他示例中)

Using return valueAt == null ? Object.class : valueAt.getClass(); 使用return valueAt == null ? Object.class : valueAt.getClass(); return valueAt == null ? Object.class : valueAt.getClass(); in your getColumnClass method is a bad idea. 在您的getColumnClass方法中是个坏主意。 You should be passing back appropriate, known values. 您应该传回适当的已知值。

Calling fireTableDataChanged in the constructor is pointless, no one could possibly have attached a listener to your model yet. 在构造函数中调用fireTableDataChanged是没有意义的,还没有人可以将侦听器附加到模型中。

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

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