
本文介绍如何通过继承 defaultglazedlistsfilterstrategy 并重写关键方法,实现对 null 值的自动忽略,从而解决 nattable 中因 null 导致的数值过滤逻辑错误(如父子行误显、比较结果失真等问题)。
本文介绍如何通过继承 defaultglazedlistsfilterstrategy 并重写关键方法,实现对 null 值的自动忽略,从而解决 nattable 中因 null 导致的数值过滤逻辑错误(如父子行误显、比较结果失真等问题)。
在 NatTable 与 GlazedLists 集成的过滤场景中,DefaultGlazedListsFilterStrategy 是默认使用的过滤策略类,它依赖于传入的 FilterComparator 对单元格值与用户输入条件进行比对。然而,其默认行为不会主动跳过 null 值——当某列(例如“Size in bytes”)存在 null 时,DefaultComparator(底层基于 String.valueOf())会将 null 转为字符串 "null",进而参与字典序比较;更严重的是,在自定义数值比较逻辑中,若未显式处理 null,compareTo() 可能抛出 NullPointerException,或返回误导性结果(如 null.compareTo(1000) → -1),导致本应被排除的空值行被判定为“匹配”,连带其父节点(树形结构中)错误地保留在过滤结果中。
要彻底规避该问题,核心思路是:不依赖 nullsFirst/nullsLast 等包装器(它们仅改变 null 的排序位置,仍参与比较),而是让过滤器在比较前直接判定——若任一操作数为 null,则立即返回 false(即不匹配),从而将 null 行完全排除在过滤结果之外。
以下是推荐的实现方案:
✅ 步骤 1:编写自定义 FilterStrategy
public class NullIgnoringNumericFilterStrategy<T> extends DefaultGlazedListsFilterStrategy<T> {
private final int columnIndex; // 指定需忽略 null 的列索引(如 Size 列)
public NullIgnoringNumericFilterStrategy(
EventList<T> eventList,
IColumnPropertyAccessor<T> columnPropertyAccessor,
int columnIndex) {
super(eventList, columnPropertyAccessor);
this.columnIndex = columnIndex;
}
@Override
protected boolean matches(T rowObject, String filterText, int columnIndex) {
// 仅对目标列做 null 过滤,其他列保持默认行为
if (columnIndex == this.columnIndex) {
Object value = getColumnPropertyAccessor().getDataValue(rowObject, columnIndex);
if (value == null) {
return false; // 明确排除 null 行,不参与任何数值比较
}
// 后续可在此处添加类型安全的数值解析与比较(如 Long.parseLong)
try {
long numericValue = Long.parseLong(String.valueOf(value).trim());
long threshold = Long.parseLong(filterText.trim());
// 示例:支持 ">=1000" 等语法需进一步解析,此处简化为等于/范围判断
return numericValue <= threshold; // 根据实际需求调整逻辑
} catch (NumberFormatException e) {
return false;
}
}
return super.matches(rowObject, filterText, columnIndex);
}
}✅ 步骤 2:注册到 NatTable 过滤配置
// 创建自定义策略(假设 Size 列索引为 2)
FilterStrategy<MyDataType> filterStrategy =
new NullIgnoringNumericFilterStrategy<>(
eventList,
columnPropertyAccessor,
2 // Size in bytes 列索引
);
// 在 NatTable 初始化时绑定
FilterRowHeaderComposite<?> filterRow = new FilterRowHeaderComposite<>(
bodyLayerStack.getFilterRowDataLayer(),
bodyLayerStack.getFilterRowLayer(),
bodyLayerStack.getBodyLayer(),
filterStrategy
);⚠️ 注意事项
- 列索引一致性:确保 columnIndex 与 IColumnPropertyAccessor 中定义的属性顺序严格一致;
- 类型安全:matches() 中的 parseLong() 仅为示例,生产环境建议使用 NumberUtils 或 Optional 封装容错解析;
- 性能考量:避免在 matches() 中执行耗时操作(如 IO、复杂正则);null 检查本身开销极低,是推荐的轻量级解决方案;
- 扩展性:如需多列 null 忽略,可将 columnIndex 改为 Set<Integer> 并在 matches() 中检查包含关系。
通过此方案,所有 Size in bytes 列为 null 的行(如图中第2–17行)将完全不参与过滤判定,既不会因 null < 1000 被误选,也不会触发父行(第1行)的级联显示,真正实现“数值过滤只作用于有效数据”的设计目标。

















