
本文介绍如何通过继承 DefaultGlazedListsFilterStrategy 并重写关键方法,实现对数值列(如“Size in bytes”)过滤时自动忽略 null 值,避免因 null 参与比较导致父行误显、过滤逻辑失效等问题。
本文介绍如何通过继承 `defaultglazedlistsfilterstrategy` 并重写关键方法,实现对数值列(如“size in bytes”)过滤时自动忽略 `null` 值,避免因 `null` 参与比较导致父行误显、过滤逻辑失效等问题。
在 NatTable 与 GlazedLists 集成的过滤场景中,DefaultGlazedListsFilterStrategy 默认使用 DefaultComparator(本质是字符串比较)进行匹配,这在处理数值型列(如字节数)时极易引发问题:当单元格值为 null 时,DefaultComparator.compare(null, 1000) 返回 -1,被判定为“满足条件”,从而错误地保留含 null 的行——尤其在树形结构中,子行 null 会连带其父行一同出现在过滤结果中,严重破坏业务语义。
要从根本上解决该问题,不应依赖 Comparator.nullsFirst() 或 Comparator.nullsLast(),因为它们仅控制 null 的排序位置,无法实现“完全排除 null 参与过滤判断”。正确做法是自定义 FilterStrategy,在匹配前主动跳过 null 值。
以下是一个生产就绪的实现方案:
public class NullSkippingNumericFilterStrategy<t> extends DefaultGlazedListsFilterStrategy<t> {
private final int numericColumnIndex; // 目标数值列索引(如 Size in bytes 列)
public NullSkippingNumericFilterStrategy(
ListEventLayer<t> eventLayer,
IRowDataProvider<t> rowDataProvider,
int numericColumnIndex) {
super(eventLayer, rowDataProvider);
this.numericColumnIndex = numericColumnIndex;
}
@Override
protected boolean matches(T element, String filterText) {
// 获取目标列的原始值
Object value = rowDataProvider.getColumnValue(element, numericColumnIndex);
// 关键:若值为 null,直接返回 false(不匹配,即被过滤掉)
if (value == null) {
return false;
}
// 对非 null 值执行原有数值/字符串匹配逻辑
// 注意:此处需确保 filterText 可安全解析为数值(如 Integer/Long)
try {
Number filterNumber = NumberUtils.createNumber(filterText.trim());
Number cellNumber = convertToNumber(value);
// 示例:支持 ">=2960"、"= filterNumber.doubleValue();
} catch (NumberFormatException e) {
// 若 filterText 非数值,则回退到字符串模糊匹配(可选)
String displayText = getDisplayText(value);
return displayText != null && displayText.contains(filterText.trim());
}
}
private Number convertToNumber(Object obj) {
if (obj instanceof Number) {
return (Number) obj;
}
if (obj instanceof String) {
return NumberUtils.createNumber((String) obj);
}
return 0; // 或抛异常,视业务容忍度而定
}
private String getDisplayText(Object obj) {
return obj == null ? "" : obj.toString();
}
}</t></t></t></t>
注册方式(在创建 FilterRow 时):
// 替换默认策略
IConfigRegistry configRegistry = new ConfigRegistry();
configRegistry.registerConfigAttribute(
FilterConfigAttributes.FILTER_STRATEGY,
new NullSkippingNumericFilterStrategy(
eventLayer,
rowDataProvider,
2 // 注意:列索引从 0 开始,Size in bytes 列为第 3 列 → 索引 2
),
DisplayMode.NORMAL
);
✅ 关键优势:
- null 值在 matches() 中被立即拦截并返回 false,彻底脱离比较流程;
- 父子行逻辑不受干扰:子行 null 不再触发父行显示;
- 可灵活扩展支持数值范围表达式(如 >,
- 保持与 NatTable 过滤框架的无缝集成,无需替换核心组件。
⚠️ 注意事项:
- 确保 numericColumnIndex 与实际数据模型列顺序严格一致;
- 若列支持多种数据类型(如 Integer/Long/BigDecimal),convertToNumber() 需增强类型适配;
- 生产环境建议对 filterText 解析增加边界校验(如空值、溢出),防止 NumberFormatException 中断过滤流程;
- 此策略仅影响指定列,其他列仍沿用默认字符串匹配,符合分列定制化需求。
通过该方案,你将获得一个健壮、可维护且语义清晰的 null 安全数值过滤能力,真正解决树形表格中因 null 引发的过滤失真问题。











