NatTable2.0.2添加SummaryRowLayer后RowIdHideShowLayer抛NPE问题
问题背景
- 升级场景:将NatTable组件从1.6.0版本升级至2.0.2版本
- 异常表现:调用
ILayerCell#getConfigLabels()方法获取配置标签时,RowIdHideShowLayer层抛出NPE(空指针异常) - 触发条件:仅在层栈中添加*Summary Row Layer(汇总行层)*时触发,未添加汇总行层时功能运行正常
- 异常堆栈:
java.lang.NullPointerException: null at java.util.TreeMap.getEntry(TreeMap.java:347) at java.util.TreeMap.containsKey(TreeMap.java:232) at org.eclipse.nebula.widgets.nattable.hideshow.RowIdHideShowLayer.isRowIndexHidden(RowIdHideShowLayer.java:191) at org.eclipse.nebula.widgets.nattable.hideshow.RowIdHideShowLayer.getConfigLabelsByPosition(RowIdHideShowLayer.java:171) at org.eclipse.nebula.widgets.nattable.layer.AbstractIndexLayerTransform.getConfigLabelsByPosition(AbstractIndexLayerTransform.java:345) at org.eclipse.nebula.widgets.nattable.selection.SelectionLayer.getConfigLabelsByPosition(SelectionLayer.java:581) at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getConfigLabelsByPosition(AbstractLayerTransform.java:341) at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer.getConfigLabelsByPosition(CompositeLayer.java:593) at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getConfigLabelsByPosition(AbstractLayerTransform.java:341) at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer.getConfigLabelsByPosition(CompositeLayer.java:593) at org.eclipse.nebula.widgets.nattable.layer.cell.AbstractLayerCell.getConfigLabels(AbstractLayerCell.java:55)
- 异常截图:

根因说明
该问题是NatTable 2.0.2版本的已知缺陷:
SummaryRowLayer渲染的汇总行为虚拟行,不存在于原始业务数据集中,没有对应的唯一rowId标识RowIdHideShowLayer内部通过TreeMap存储已隐藏行的rowId映射,而TreeMap原生不支持null作为查询键- 当层栈组装顺序错误时,
RowIdHideShowLayer会尝试处理汇总行的查询逻辑,拿到null类型的rowId后直接调用TreeMap.containsKey(null),触发空指针。
修复方案
可根据实际项目场景选择以下任意一种方案修复:
- 方案1:调整层栈组装顺序(无侵入,优先推荐)
调整NatTable层组装顺序,将RowIdHideShowLayer放在SummaryRowLayer的下层(更靠近数据层的一侧),确保RowIdHideShowLayer仅处理真实业务数据行,不会接触到上层虚拟生成的汇总行。标准层栈顺序(从底层数据侧到上层视图侧)参考:DataLayer → RowIdHideShowLayer → SummaryRowLayer → SelectionLayer → ViewportLayer - 方案2:升级官方修复版本
直接将NatTable依赖升级至2.1.0及以上正式版本,官方已在该版本中为RowIdHideShowLayer增加了null rowId的判空逻辑,可自动兼容汇总行等虚拟行场景,无需额外修改业务代码。 - 方案3:自定义层临时修复(无法调整顺序/升级版本时使用)
继承原生RowIdHideShowLayer,重写isRowIndexHidden方法增加null判断,逻辑参考:
层组装时使用自定义的public class FixedRowIdHideShowLayer extends RowIdHideShowLayer { public FixedRowIdHideShowLayer(ILayer underlyingLayer, IRowIdAccessor<?> rowIdAccessor) { super(underlyingLayer, rowIdAccessor); } @Override public boolean isRowIndexHidden(int rowIndex) { Object rowId = getRowIdByIndex(rowIndex); // 无rowId的为虚拟行(如汇总行),默认不属于隐藏行 if (rowId == null) { return false; } return super.isRowIndexHidden(rowIndex); } }FixedRowIdHideShowLayer替换原生RowIdHideShowLayer即可解决问题。
内容的提问来源于stack exchange,提问作者SeemaC
相关产品推荐
相关产品推荐

