简体   繁体   中英

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. 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.

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.

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.

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)

Using return valueAt == null ? Object.class : valueAt.getClass(); return valueAt == null ? Object.class : valueAt.getClass(); in your getColumnClass method is a bad idea. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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