Java Swing带复选框的表格搜索时复选框消失如何解决

问题根因
每次触发按键释放事件时调用Jtable.setModel(new DefaultTableModel(...))会直接替换整个表格模型,存在两个问题:
- 新创建的
DefaultTableModel默认所有列类型为Object,Swing JTable仅当列类型声明为Boolean时才会自动渲染为复选框 - 直接替换模型会完全丢失原表格里的复选框选中状态
解决方法
不要每次搜索都重建整个表格模型,改用Swing自带的TableRowFilter实现搜索过滤,该方案仅控制行的显示/隐藏,不会修改原模型数据,能完整保留复选框渲染规则和选中状态。
具体实现步骤
- 初始化表格时就固定原始模型,重写
getColumnClass方法指定复选框列的类型:
// 初始化原始表格模型,仅执行一次 DefaultTableModel originalModel = new DefaultTableModel(new Object[]{"Name","code","section","credit","type","hours","semestre","选择"}, 0) { @Override public Class<?> getColumnClass(int columnIndex) { // 第8列(索引7)为复选框列,返回Boolean类型触发复选框渲染 if (columnIndex == 7) { return Boolean.class; } return super.getColumnClass(columnIndex); } }; // 给表格绑定排序过滤器,用于后续搜索 TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<>(originalModel); table.setRowSorter(sorter); table.setModel(originalModel); // 所有原始表格数据统一添加到originalModel中,后续不要随意替换模型 // 示例添加数据:originalModel.addRow(new Object[]{"高等数学","001","A","4","必修","64","1", false});
- 删掉原有按键释放事件中替换模型的代码,替换为过滤逻辑:
// 按键释放事件中的搜索逻辑 String searchText = 搜索输入框.getText().trim(); if (searchText.isEmpty()) { // 搜索内容为空时显示所有行 sorter.setRowFilter(null); } else { // (?i) 代表忽略大小写,后面的0代表仅匹配Name列,如需匹配多列可改为{0,1}同时匹配Name和code列 sorter.setRowFilter(RowFilter.regexFilter("(?i)" + searchText, 0)); }
如果确实有特殊场景必须重建模型,需要保证新模型同样重写getColumnClass返回复选框列的Boolean类型,并且手动同步原模型中所有行的复选框选中状态到新模型,该方案性能远低于过滤方案,不推荐。
内容的提问来源于stack exchange,提问作者Aly
相关产品推荐
相关产品推荐

