编辑JTable单元格后如何获取选中的行和列?
解决JTable编辑完成后获取选中行/列的问题
老哥你踩的这个坑其实很常见——TableModelEvent的事件源本来就是TableModel(这里就是你用的DefaultTableModel),不是JTable实例,所以强转肯定会报错。下面给你两种靠谱的解决思路,按需选择:
方法一:直接引用外部的JTable实例(最简单)
在Java 8及以上版本中,局部变量只要是「有效final」(即声明后没有被重新赋值),就可以在内部类中直接引用。你可以直接在tableChanged方法里调用外部的table对象的选中行/列方法:
public static void main(String[] args) { JFrame main = new JFrame(); // 这里table是有效final的,内部类可以直接访问 JTable table = new JTable(6, 4); table.setSize(300, 300); table.getModel().addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent e) { // 直接获取选中的行和列 int row = table.getSelectedRow(); int col = table.getSelectedColumn(); // 增加判断,避免非编辑场景下的-1值 if (row != -1 && col != -1) { System.out.println("Edited cell at " + row + "," + col); // 还可以拿到修改后的单元格值 Object newValue = table.getValueAt(row, col); System.out.println("New value: " + newValue); } } }); main.add(table); main.setSize(300,300); main.setLocationRelativeTo(null); main.setVisible(true); main.setDefaultCloseOperation(DISPOSE_ON_CLOSE); }
方法二:使用CellEditorListener(更精准监听编辑事件)
如果你的需求是仅在用户完成单元格编辑时触发操作,而不是监听所有模型数据变化(比如代码修改模型也会触发TableModelListener),那么使用CellEditorListener会更精准:
public static void main(String[] args) { JFrame main = new JFrame(); JTable table = new JTable(6, 4); table.setSize(300, 300); // 给默认单元格编辑器添加监听器 table.getDefaultEditor(Object.class).addCellEditorListener(new CellEditorListener() { @Override public void editingStopped(ChangeEvent e) { // 获取正在编辑的行和列(编辑完成时依然有效) int editRow = table.getEditingRow(); int editCol = table.getEditingColumn(); if (editRow != -1 && editCol != -1) { System.out.println("Editing finished at cell: " + editRow + "," + editCol); Object newValue = table.getValueAt(editRow, editCol); System.out.println("Updated value: " + newValue); } } @Override public void editingCanceled(ChangeEvent e) { // 可选:处理编辑取消的场景 System.out.println("Editing was canceled"); } }); main.add(table); main.setSize(300,300); main.setLocationRelativeTo(null); main.setVisible(true); main.setDefaultCloseOperation(DISPOSE_ON_CLOSE); }
为什么原来的代码会出错?
TableModelListener是监听数据模型的变化,不管是用户编辑单元格,还是通过代码直接修改TableModel的数据,都会触发这个事件。所以e.getSource()返回的是触发事件的TableModel实例,而非JTable视图组件,强转自然会抛出类型转换异常。
内容的提问来源于stack exchange,提问作者Darrius
相关产品推荐
相关产品推荐

