Domanda

How do I listen for changes in a JTable column that has a JCheckBox in it? I want to know when the user selects/deselects the check box. The class for the column is set as boolean so it is automatically rendered as a JCheckBox.

È stato utile?

Soluzione 2

Thanks to the comment by mKorbel, I re-wrote the setValueAt method for the table model as such:

public void setValueAt(Object value, int row, int col) {
    super.setValueAt(value, row, col);
    if (col == 4) {
        if ((Boolean) this.getValueAt(row, col) == true) {
            //code goes here
        }
        else if ((Boolean) this.getValueAt(row, col) == false) {
            //code goes here
        }
    }   
}

Now the code is only executed when the value in the cell actually changes, which is what I want.

Altri suggerimenti

I think what you want is to listen for data changes in the TableModel by using a TableModelListener. It's also possible to use a custom editor, but I think the TableModelListener is the simplest way to go. Your overriden tableChanged method could look something like this

@Override
public void tableChanged(TableModelEvent e) {
    int row = e.getFirstRow();
    int column = e.getColumn();
    if (column == BOOLEAN_COLUMN) {
        TableModel model = (TableModel) e.getSource();
        String columnName = model.getColumnName(column);
        Boolean checked = (Boolean) model.getValueAt(row, column);
        if (checked) {
            System.out.println(columnName + ": " + true);
        } else {
            System.out.println(columnName + ": " + false);
        }
    }
}

enter image description here

Here's a complete running example

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class TestTableModelListener {
    private static final int BOOLEAN_COLUMN = 2;

    public TestTableModelListener() {
        JTable table = createTable();
        table.getModel().addTableModelListener(new CheckBoxModelListener());

        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTable createTable() {
        String[] cols = {"COL", "COL", "COL"};
        Object[][] data = {{"Hello", "Hello", false}, {"Hello", "Hello", false}};
        DefaultTableModel model = new DefaultTableModel(data, cols) {
            @Override
            public Class getColumnClass(int column) {
                return column == BOOLEAN_COLUMN ? Boolean.class : String.class;
            }
        };
        JTable table = new JTable(model);
        return table;
    }

    public class CheckBoxModelListener implements TableModelListener {

        public void tableChanged(TableModelEvent e) {
            int row = e.getFirstRow();
            int column = e.getColumn();
            if (column == BOOLEAN_COLUMN) {
                TableModel model = (TableModel) e.getSource();
                String columnName = model.getColumnName(column);
                Boolean checked = (Boolean) model.getValueAt(row, column);
                if (checked) {
                    System.out.println(columnName + ": " + true);
                } else {
                    System.out.println(columnName + ": " + false);
                }
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestTableModelListener();
            }
        });
    }
}

Now the code is only executed when the value in the cell actually changes, which is what I want.

Check out the Table Cell Listener which was specifically designed for this situation.

Other way, it is create an MouseClicked event in the JTable, the event is fired when you click in somewhere in the jtable. Inside the event, we save the number of row and number of column. Then we imagine that we have two checkbox in column 4 and column 5 of Jtable. For example, if we pressed row 2 and column 4, we mark the checkbox in the JTable and we save the boolean value of the checbox in a dataBase using an update sql sentence.

private void RegistroFacturaTableMouseClicked(java.awt.event.MouseEvent evt) {                                                  
        int filaSeleccionada = RegistroFacturaTable.rowAtPoint(evt.getPoint());
        int columnaSeleccionada = RegistroFacturaTable.columnAtPoint(evt.getPoint());
        if(evt.getClickCount() == 2){
            int idRegistroFactura = (int) RegistroFacturaTable.getValueAt(filaSeleccionada, 0);
            setVisible(false);
            new VerCobros(this, idRegistroFactura, contrato);
        } else if (columnaSeleccionada == 4 ){
            int idRegistroFactura = (int) RegistroFacturaTable.getValueAt(filaSeleccionada, 0);
            boolean agua = (boolean) RegistroFacturaTable.getValueAt(filaSeleccionada, 4);
            DataBase.updateRegistroFacturaSetAguaWhereIdRegistroFactura(agua, idRegistroFactura); 
        } else if ( columnaSeleccionada == 5 ){
           int idRegistroFactura = (int) RegistroFacturaTable.getValueAt(filaSeleccionada, 0);
           boolean luz = (boolean) RegistroFacturaTable.getValueAt(filaSeleccionada, 5);
           DataBase.updateRegistroFacturaSetLuzWhereIdRegistroFactura(luz, idRegistroFactura);
        }      
    }   
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top