You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NatTable排序/过滤时自动调整行高功能实现失败求助

NatTable排序/过滤时自动调整行高失效问题

我无法实现NatTable在排序或过滤时自动调整行高的功能。尝试过官方的AutomaticRowHeightExample示例,也参考过官方论坛的相关解决方案,但都没成功。执行排序/过滤操作时,控制台能输出绘制行的序号i,但行高并未更新。

创建表格的核心代码

public class NatTableFactory {
  
  // 其他代码省略

  private NatTable createTable(Composite parent, List<TableLine> tLines, String[][] propertyNames,
      PropertyToLabels[] propToLabels, TableParams params, TextMatcherEditor<TableLine>editor, boolean openableParts) {
    
    BodyLayerStack bodyLayerStack =
        new BodyLayerStack(
                tLines,
                tLines.get(0).getLength(),
                params.getColumnIndicesForRowHeaders());
    
    DataLayer bodyDataLayer = bodyLayerStack.getBodyDataLayer();
    Integer[] rowHeights = getRowHeights(params);
    if( rowHeights != null && rowHeights.length > 0 ) {
      for( int i = 0; i < rowHeights.length; i++ ) {
        if( rowHeights[i] != null )
          bodyDataLayer.setRowHeightByPosition(i, (int) (rowHeights[i] * ApplicationSizeManager.getRowSizeCoefficient()));
      }
    }
    Integer[] colWidths = getColumnWidths(params);
    if( colWidths != null && colWidths.length > 0 ) {
      for( int i = 0; i < colWidths.length; i++ )
        if( colWidths[i] != null )
          bodyDataLayer.setColumnWidthByPosition(i, colWidths[i]);
    }

    DataLayer columnHeaderDataLayer = null;
    if( propertyNames != null ) {
      IDataProvider columnHeaderDataProvider = 
          new DefaultColumnHeaderDataProvider(propertyNames[0], propToLabels[0].getPropertyToLabels());
      columnHeaderDataLayer =
          new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
    }

    // 复制命令:包含表头
    bodyLayerStack.registerCommandHandler(new CustomCopyDataCommandHandler(bodyLayerStack.getSelectionLayer(), columnHeaderDataLayer, null, params.getColumnHeaderGroups()));

    CompositeLayer composite = null;
    if( propertyNames != null ) {
      ColumnHeaderLayer columnHeaderLayer =
          new ColumnHeaderLayer(
              columnHeaderDataLayer,
              bodyLayerStack,
              (SelectionLayer)null);
      columnHeaderLayer.addConfiguration(NatTableLayerConfigurations.getColumnHeaderLayerConfiguration(false));

      SortHeaderLayer<TableLine> sortHeaderLayer =
          new SortHeaderLayer<TableLine>(
              columnHeaderLayer,
              new GlazedListsSortModel<TableLine>(
                  bodyLayerStack.getSortedList(),
                  getSortingColumnPropAccessor(propertyNames[0]),
                  configRegistry,
                  columnHeaderDataLayer));

      Integer[] hrHeights = params.getHeaderRowHeights();
      if( hrHeights != null && hrHeights.length > 0 )
        columnHeaderDataLayer.setRowHeightByPosition(0, (int) (hrHeights[0] * ApplicationSizeManager.getRowSizeCoefficient()));
      
      composite = new CompositeLayer(1, 2);
      composite.setChildLayer(GridRegion.COLUMN_HEADER, sortHeaderLayer, 0, 0);
      composite.setChildLayer(GridRegion.BODY, bodyLayerStack, 0, 1);
    } else {
      composite = new CompositeLayer(1, 1);
      composite.setChildLayer(GridRegion.BODY, bodyLayerStack, 0, 0);
    }
    
    composite.addConfiguration(NatTableLayerConfigurations.getCompoositeLayerConfiguration());
    
    NatTable natTable = new NatTable(parent, composite, false);
    
    if( params.getAutoFitColWidthIndices().size() > 0 )
      registerAutoResizeColCmdHandler(natTable, composite, bodyLayerStack, params.getAutoFitColWidthIndices());
    
    // 注册自动调整行高命令处理器,这里可能有问题?
    registerAutoResizeRowCommandHandler(natTable, composite, bodyLayerStack, params.getAutoFitColWidthIndices());
    
    setNatTableContentTooltip(natTable);
    
    natTable.setConfigRegistry(configRegistry);
   
    natTable.addConfiguration(new SingleClickSortConfiguration());
    
    if(columnHeaderDataLayer!=null)
      natTable.addConfiguration(NatTableLayerConfigurations.getCustomComparatorConfiguration(columnHeaderDataLayer));
    
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration());

    setNatTableContextMenu(natTable, openableParts);
    
    natTable.addConfiguration(NatTableLayerConfigurations.getNatTableConfiguration());
    
    // 以下是注释掉的自动行高绘制器尝试
    /*
    natTable.addConfiguration(new DefaultNatTableStyleConfiguration()
    {
      {
        cellPainter = new LineBorderDecorator(new AutomaticRowHeightTextPainter(5));
      }
    });*/
   
    natTable.configure();

    editor.setFilterator(new TextFilterator<TableLine>() {

      @Override
      public void getFilterStrings(List<String> baseList, TableLine element) {
        for( int i = 0; i < element.getLength(); i++ )
          baseList.add("" + element.getObjectByColumnForFilter(i));
      }
    });
    editor.setMode(TextMatcherEditor.REGULAR_EXPRESSION);
    bodyLayerStack.getFilterList().setMatcherEditor(editor);

    NatTableContentProvider.addNatTableData(natTable, bodyLayerStack.getSelectionLayer(), bodyLayerStack.getBodyDataProvider());
    
    return natTable;
  }
  
  // 其他代码省略
}

注册自动调整行高命令处理器的代码

// 在NatTableFactory类中
private void registerAutoResizeRowCommandHandler(NatTable natTable, ILayer commandLayer, ILayer positionLayer, List<Integer> colPositions)
{
  natTable.registerCommandHandler(new AutoResizeRowCommandHandler(commandLayer, positionLayer));
  PaintListener listener = new PaintListener()
  {
    @Override
    public void paintControl(PaintEvent e)
    {
      System.out.println("paintControl");
      for (int i = 0; i < natTable.getRowCount(); i++)
      {
        System.out.println(i);
        InitializeAutoResizeRowsCommand rowCommand = new InitializeAutoResizeRowsCommand(natTable, i, natTable.getConfigRegistry(), new GCFactory(
              natTable));
        AutoResizeRowsCommand command = new AutoResizeRowsCommand(rowCommand);
        natTable.doCommand(command);
      }
    }
  };
  natTable.addPaintListener(listener);
}

BodyLayerStack实现代码

public BodyLayerStack(List<TableLine> values, int columnCount, Integer[] columnIndicesForRowHeaders)
  {
    EventList<TableLine> eventList = GlazedLists.eventList(values);
    TransformedList<TableLine, TableLine> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);

    // 原代码注释:改为使用SortedList构造器并传入null作为Comparator,因为Comparator将通过配置设置
    sortedList = new SortedList<>(rowObjectsGlazedList, null);
    // 用FilterList包裹SortedList
    filterList = new FilterList<>(sortedList);
    
    bodyDataProvider = new ListDataProvider<TableLine>(filterList, getColumnAccessor(columnCount));
    bodyDataLayer = new DataLayer(bodyDataProvider);

    IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
      
      @Override
      public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
        int columnIndex = bodyDataLayer.getColumnIndexByPosition(columnPosition);
        int rowIndex = bodyDataLayer.getRowIndexByPosition(rowPosition);

        if(isRowHeader(columnIndicesForRowHeaders, columnIndex)) 
          configLabels.addLabel(NatTableFactory.RowHeaderLabel);
        else
        {
          // 获取实际位置的数据类型并添加/刷新标签
          String label = filterList.get(rowIndex).getObjectTypeByColumn(columnIndex);
          // 根据自动适配宽度选项调整标签
          if(filterList.get(rowIndex).isAutoFitColWidth(columnIndex))
            label += "_" + NatTableFactory.AutoFitWidthLabel;
          else
            label += "_" + NatTableFactory.NoAutoFitWidthLabel; 
          configLabels.addLabel(label);
        }
      }
    };
    bodyDataLayer.setConfigLabelAccumulator(cellLabelAccumulator);

    GlazedListsEventLayer<TableLine> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer, filterList);
    
    selectionLayer = new SelectionLayer(glazedListsEventLayer, false);
    selectionLayer.setSelectionModel(getSelectionModel());
    selectionLayer.addConfiguration(getSelectionConfiguration());
    
    viewportLayer = new ViewportLayer(selectionLayer);
    setUnderlyingLayer(new ViewportLayer(selectionLayer));

  }

其他尝试过的方案

如果调用natTable.doCommand(rowCommand)替代natTable.doCommand(command),行高能正确更新,但表格会重复绘制,滚动条持续闪烁。还尝试过以下代码:

private void registerAutoResizeRowCommandHandler(NatTable natTable, ILayer commandLayer, ILayer positionLayer, List<Integer> colPositions)
  {
    natTable.registerCommandHandler(new AutoResizeRowCommandHandler(commandLayer, positionLayer));
    BodyLayerStack bodyLayerStack = (BodyLayerStack) positionLayer;
    natTable.addPaintListener(
        new AutoResizeRowPaintListener(
            natTable, 
            bodyLayerStack.getViewportLayer(), 
            bodyLayerStack.getBodyDataLayer()));
  }

请问我遗漏了什么?


内容的提问来源于stack exchange,提问作者stojelenov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:40:39