JTable单元格选择异常:取消单个选中项致全部选中项被取消
问题描述
我有一个支持单元格选择的JTable,当通过Ctrl+点击选中第一列的第1行和第2行后,取消其中一行的选中状态时,另一行的选中状态也会被取消。
相关代码如下:
public static void main(String[] args) { JFrame jf = new JFrame("Test"); JTable table = new JTable(); table.setCellSelectionEnabled(true); DefaultTableModel tm = new DefaultTableModel(new Object[][]{new Object[]{1,"A"},new Object[]{2, "B"},new Object[]{3, "C"}}, new Object[]{"Test", "Test2"}); table.setModel(tm); jf.setSize(300, 400); jf.getContentPane().add(table); jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jf.setLocationRelativeTo(null); jf.setVisible(true); }
经分析Swing底层代码,问题根源在于:当列0处于选中状态时,取消单个单元格会触发列选择模型清空全部选择,表格重绘后无列选中状态,进而导致所有选中项被清空。请问能否在不重写整个DefaultSelectionModel的前提下避免全部选中项被取消?
解决方案
可以通过**自定义列选择模型的子类(仅重写必要方法)**来解决,无需重写整个DefaultSelectionModel,核心是拦截列选择模型的不当清空操作:
public static void main(String[] args) { JFrame jf = new JFrame("Test"); JTable table = new JTable(); table.setCellSelectionEnabled(true); // 替换列选择模型,仅重写clearSelection方法拦截不合理清空 table.setColumnSelectionModel(new DefaultListSelectionModel() { @Override public void clearSelection() { // 判断当前场景:单元格选择模式下,仍有选中行且仅当前列被选中 if (table.getCellSelectionEnabled() && table.getSelectedRowCount() > 1 && getSelectedIndices().length == 1) { // 拦截默认清空操作,避免连带清空行选择 return; } // 其他正常场景执行默认清空逻辑 super.clearSelection(); } }); DefaultTableModel tm = new DefaultTableModel( new Object[][]{{1, "A"}, {2, "B"}, {3, "C"}}, new Object[]{"Test", "Test2"}); table.setModel(tm); jf.setSize(300, 400); jf.getContentPane().add(table); jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jf.setLocationRelativeTo(null); jf.setVisible(true); }
这个方案仅对列选择模型的clearSelection方法做针对性修改,只拦截“取消单个单元格导致列选择被清空”的异常场景,其他正常选择逻辑不受影响,完全符合“不重写整个DefaultSelectionModel”的要求。
内容的提问来源于stack exchange,提问作者siggemannen
相关产品推荐
相关产品推荐

