Java如何组合列表型andFilter与orFilter实现JTable类Excel多列筛选
JTable实现Excel式多列组合筛选实现方案
核心逻辑对齐
不要把所有单值筛选器平铺存储后做同层级合并,按照规则分层处理即可:
- 同一列下的多个勾选值:采用OR逻辑合并,命中任意值即通过该列筛选
- 不同列的筛选结果:采用AND逻辑合并,所有列筛选都通过的行才会展示
- 单值匹配采用
regexFilter实现精确字符串匹配,避免模糊匹配误命中
具体实现步骤
- 调整筛选器存储结构,放弃平铺的
List<RowFilter>存储方式,改用Map<Integer, List<RowFilter<TableModel, Object>>>按列索引分组存储,key为列序号,value为该列下所有勾选值对应的精确匹配筛选器。 - 分两层合并筛选器:
- 第一层:遍历每一列对应的筛选器列表,调用
RowFilter.orFilter()合并为单列总筛选器,实现同列多值的或逻辑 - 第二层:把所有列合并后的单列筛选器收集为新列表,调用
RowFilter.andFilter()合并为最终的全局筛选器,实现跨列的与逻辑
- 第一层:遍历每一列对应的筛选器列表,调用
- 把最终合并完成的筛选器设置到
TableRowSorter即可生效。
可直接复用的代码示例
import javax.swing.*; import javax.swing.table.TableModel; import javax.swing.table.TableRowSorter; import java.util.*; import java.util.regex.Pattern; public class ExcelStyleTableFilter { private final TableRowSorter<TableModel> tableSorter; // 按列索引分组存储单值筛选器 private final Map<Integer, List<RowFilter<TableModel, Object>>> columnFilterMap = new HashMap<>(); public ExcelStyleTableFilter(JTable targetTable) { this.tableSorter = new TableRowSorter<>(targetTable.getModel()); targetTable.setRowSorter(tableSorter); } /** * 勾选筛选值时调用,给指定列添加精确匹配规则 * @param columnIndex 目标列索引 * @param exactMatchValue 勾选的精确单元格值 */ public void addFilterValue(int columnIndex, String exactMatchValue) { // 转义正则特殊字符,加起止锚点实现完全精确匹配 String regex = "^" + Pattern.quote(exactMatchValue) + "$"; RowFilter<TableModel, Object> singleValueFilter = RowFilter.regexFilter(regex, columnIndex); columnFilterMap.computeIfAbsent(columnIndex, k -> new ArrayList<>()).add(singleValueFilter); refreshCombinedFilter(); } /** * 取消勾选筛选值时调用,移除对应匹配规则 */ public void removeFilterValue(int columnIndex, String exactMatchValue) { List<RowFilter<TableModel, Object>> colFilters = columnFilterMap.get(columnIndex); if (colFilters == null) return; // 实际业务中可给单值filter加标记做精准移除,简化场景下可在勾选变化时全量重建该列filter列表 String targetRegex = "^" + Pattern.quote(exactMatchValue) + "$"; colFilters.removeIf(filter -> filter.toString().contains(targetRegex)); if (colFilters.isEmpty()) columnFilterMap.remove(columnIndex); refreshCombinedFilter(); } /** * 分层合并所有筛选规则并应用到表格 */ private void refreshCombinedFilter() { List<RowFilter<TableModel, Object>> crossColFilters = new ArrayList<>(); // 第一步:同列多值做OR合并 for (List<RowFilter<TableModel, Object>> singleColFilters : columnFilterMap.values()) { if (singleColFilters.isEmpty()) continue; crossColFilters.add(RowFilter.orFilter(singleColFilters)); } // 第二步:跨列规则做AND合并 RowFilter<TableModel, Object> finalFilter = crossColFilters.isEmpty() ? null // 无筛选规则时展示全部行 : RowFilter.andFilter(crossColFilters); tableSorter.setRowFilter(finalFilter); } }
注意事项
- 构造单值正则筛选器时必须用
Pattern.quote()转义值中的特殊字符(比如示例中的逗号、百分号、小数点等),同时加^和$锚定匹配起止,避免出现部分匹配、正则语法报错的问题 - Swing自带的
RowFilter.andFilter()、RowFilter.orFilter()原生支持任意层级嵌套,不需要自定义RowFilter实现即可满足分层逻辑需求 - 给
regexFilter传入列索引参数后,筛选器只会校验对应列的值,不需要手动写列判断逻辑,性能更高也不容易出错
内容的提问来源于stack exchange,提问作者TomC
相关产品推荐
相关产品推荐

