Java JTable RowFilter无法正常工作,请求排查问题
问题:JTable RowFilter过滤后显示空白的排查
问题描述
我有一个基于DefaultTableModel的JTable,需要对其中的数据进行过滤。程序能正确判断需要过滤的行,将对应列的字符串转为正则表达式后添加到RowFilter列表,再通过RowFilter.andFilter设置过滤器。但设置后表格常显示空白或异常数据,我试过多种正则写法(比如加^$、括号等)都没用,而且至少应该保留6行数据。
调试确认判断过滤的布尔值missing是正确的,但表格始终空白。我提供了可复现的MCVE代码,点击Filter按钮后表格就变空白,实际应该显示排除选中项后的多行数据,求帮忙排查错误原因。
核心过滤代码
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel()); sorter.setRowFilter(null); table.setRowSorter(sorter); List<RowFilter<Object, Object>> filterList = new ArrayList<RowFilter<Object, Object>>(); boolean missing = false; //判断是否需要过滤的逻辑 if (missing) filterList.add(RowFilter.regexFilter(dataString)); //dataString为待过滤行指定列的字符串
设置过滤器的代码:
sorter.setRowFilter(RowFilter.andFilter(filterList, 5));
可复现MCVE代码
import java.awt.FlowLayout; import java.util.ArrayList; import java.util.List; import javax.swing.JPanel; import javax.swing.RowFilter; import javax.swing.table.*; public class mainTable extends javax.swing.JFrame { private TableRowSorter<TableModel> sorter; public mainTable() { initComponents(); sorter = new TableRowSorter<>(table.getModel()); sorter.setRowFilter(null); table.setRowSorter(sorter); setTable(); setCombo(); } private void initComponents() { jPanel = new JPanel(); table = new javax.swing.JTable(); comboBox = new javax.swing.JComboBox<>(); jButton1 = new javax.swing.JButton(); setLayout(new FlowLayout()); setSize(400, 400); DefaultTableModel tableModel = new DefaultTableModel(); tableModel.addColumn("Stadt"); tableModel.addColumn("Landkreis"); table.setModel(tableModel); jButton1.setText("Filter"); jButton1.addActionListener(this::jButton1ActionPerformed); jPanel.add(comboBox); jPanel.add(jButton1); jPanel.add(table); getContentPane().add(jPanel); } private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { filter(); } public static void main(String args[]) { new mainTable().setVisible(true); } private void setTable() { ArrayList<String> cities = new ArrayList<>(); ArrayList<String> landkreise = new ArrayList<>(); String[] rows = new String[2]; DefaultTableModel tbm = (DefaultTableModel) table.getModel(); cities.add("Husum"); cities.add("Westerland"); cities.add("Hannover"); cities.add("Uelzen"); cities.add("Rotenburg"); cities.add("Verden"); cities.add("Nienburg"); landkreise.add("Nordfriesland"); landkreise.add("Nordfriesland"); landkreise.add("Region Hannover"); landkreise.add("Uelzen"); landkreise.add("Rotenburg"); landkreise.add("Verden"); landkreise.add("Nienburg"); for (int i = 0; i < cities.size(); i++) { rows[0] = cities.get(i); rows[1] = landkreise.get(i); tbm.addRow(rows); } } private void setCombo() { DefaultTableModel tbm = (DefaultTableModel) table.getModel(); for (int i = 0; i < tbm.getRowCount(); i++) comboBox.addItem(tbm.getValueAt(i, 1).toString()); } private void filter() { sorter.setRowFilter(null); String filterText = comboBox.getSelectedItem().toString(); List<RowFilter<Object, Object>> filterLandkreis = new ArrayList<RowFilter<Object, Object>>(); for (int i = table.getRowCount(); i > 0; i--) { boolean filter = false; filter = !table.getValueAt(i-1, 1).toString().equals(filterText); //不显示下拉框选中值的行 if (filter) filterLandkreis.add(RowFilter.regexFilter(table.getValueAt(i-1, 1).toString())); } sorter.setRowFilter(RowFilter.andFilter(filterLandkreis)); } private javax.swing.JComboBox<String> comboBox; private javax.swing.JButton jButton1; private JPanel jPanel; private javax.swing.JTable table;
错误原因分析与修复
核心错误点
RowFilter.andFilter逻辑误用:andFilter要求所有过滤器条件同时满足才会显示行。你把所有需要保留的行的Landkreis值加入过滤器列表,意味着只有某一行的Landkreis同时等于所有这些值时才会显示——这显然不可能,导致表格空白。- 未指定正则匹配的列:
RowFilter.regexFilter(dataString)会匹配表格所有列,而你只需要匹配第二列(索引1)的Landkreis值。 - 遍历行的方式错误:使用
table.getRowCount()和table.getValueAt时,如果之前有过滤器生效,获取的是过滤后的行索引,应该直接操作TableModel的数据。
修复后的filter()方法
private void filter() { String filterText = comboBox.getSelectedItem().toString(); // 排除选中的Landkreis值,仅匹配第二列(索引1) RowFilter<Object, Object> filter = RowFilter.notFilter(RowFilter.regexFilter(filterText, 1)); sorter.setRowFilter(filter); }
额外优化建议
- 初始化
comboBox时可以对选项去重,避免重复的Landkreis选项。 - 直接基于
TableModel构建过滤逻辑,避免因过滤器生效导致的行索引混乱。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

