如何在 NatTables 的一列中对各种数据类型进行排序

问题描述

我确实将 Nattable 中的所有值都作为字符串。我使用了 IConfigLabelAccumulator 并为单元格添加标签 DataTypestringLabel = "String"DataTypeNumberLabel = "Number"在一列中可以是具有两种类型标签的值

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

    // this.filterList = new FilterList<>(rowObjectsGlazedList); //changed to:
    // use the SortedList constructor with 'null' for the Comparator
    // because the Comparator will be set by configuration
    sortedList = new SortedList<>(rowObjectsGlazedList,null);
    // wrap the SortedList with the FilterList
    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 {
          // get dataTypes at actual positions and add/refresh labels 
          configLabels.addLabel(filterList.get(rowIndex).getobjectTypeByColumn(columnIndex));
          if(configLabels.getLabels().get(0) != null && configLabels.getLabels().get(0)=="Number") {
            System.out.println("Number");                
          }
        }
      }
    };
    bodyDataLayer.setConfigLabelAccumulator(cellLabelAccumulator);
    
    GlazedListsEventLayer<TableLine> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer,filterList);
    
    selectionLayer = new SelectionLayer(glazedListsEventLayer,false);
    selectionLayer.setSelectionModel(getSelectionModel());
    selectionLayer.addConfiguration(getSelectionConfiguration());
    
    setUnderlyingLayer(new ViewportLayer(selectionLayer));
  }

目前,所有值都按字符串排序(如预期)。但我需要将标签Number 的值作为数字进行排序。

哪个更好:将数据转换为数字,还是使用自定义比较器?

  • 如果我使用数据转换,数据转换只是为了排序?排序后我需要将数据保留为字符串。
  • 如果我使用自定义比较器,我不确定如何注册标签。我应该使用已经创建的 IConfigLabelAccumulator cellLabelAccumulator 吗?

我正在尝试:

  public static IConfiguration getCustomComparatorConfiguration(final AbstractLayer columnHeaderDataLayer) {
    return new AbstractRegistryConfiguration() {

      @Override
      public void configureRegistry(IConfigRegistry configRegistry) {
        
        // Register labels
        BodyLayerStack.super.getConfigLabelAccumulator().registerOverride( //ERROR
            4,//here should come index of sorted column?
                NatTableFactory.DataTypeNumberLabel);

        // Register custom comparator
        configRegistry.registerConfigAttribute(
                SortConfigAttributes.soRT_COMParaTOR,NatTableLayerConfigurations.getCustomComparator(),displayMode.norMAL,NatTableFactory.DataTypeNumberLabel);
      }
    };
  }

但我得到 The method registerOverride(int,String) is undefined for the type IConfigLabelAccumulator

解决方法

您得到一个不提供 IConfigLabelAccumulator 方法的 registerOverride(int,String)。不确定哪个子类定义了该方法。 ColumnOverrideLabelAccumulator 提供了方法 registerColumnOverride(int,String)

如果基于字符串表示的排序不够,我建议使用自定义 Comparator

https://www.eclipse.org/nattable/documentation.php?page=sorting