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.
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);
}
}
}
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();
}
});
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With