如何监听包含JCheckBox的JTable列中的更改?我想知道用户何时选择/取消选中复选框。该列的类设置为boolean,因此它将自动呈现为JCheckBox。
答案 0 :(得分:9)
我认为您想要的是使用TableModelListener
来监听TableModel
中的数据更改。也可以使用自定义编辑器,但我认为TableModelListener
是最简单的方法。您的覆盖tableChanged
方法看起来像这样
@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);
}
}
}
这是一个完整的运行示例
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();
}
});
}
}
答案 1 :(得分:1)
感谢mKorbel的评论,我为表模型重写了setValueAt方法:
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
}
}
}
现在代码只在单元格中的值实际发生变化时执行,这就是我想要的。
答案 2 :(得分:0)
现在代码只在单元格中的值实际发生变化时执行,这就是我想要的。
查看专为此情况设计的Table Cell Listener。
答案 3 :(得分:0)
另一种方法是在JTable中创建一个MouseClicked事件,当您在jtable中的某个位置单击时会触发该事件。在事件内部,我们保存行数和列数。然后我们想象在Jtable的第4列和第5列中有两个复选框。例如,如果我们按了第2行和第4列,则标记了JTable中的复选框,然后使用更新sql语句将checbox的布尔值保存在数据库中。
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);
}
}