java.lang.Object
org.eclipse.nebula.widgets.nattable.layer.AbstractLayer
org.eclipse.nebula.widgets.nattable.layer.DataLayer
org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByDataLayer<T>
Type Parameters:
T - The type of the row objects.
All Implemented Interfaces:
Observer, ILayer, ILayerListener, IUniqueIndexLayer, IPersistable

public class GroupByDataLayer<T> extends DataLayer implements Observer
Specialized DataLayer that needs to be used in the body layer stack for adding the groupBy feature to a NatTable composition. Internally creates a TreeList and a IDataProvider for Objects, necessary as dynamically new GroupByObjects will be added to the TreeList by the GroupByTreeFormat.

This layer also supports calculating summary values for created groups. Note that it is necessary to call initializeTreeComparator(ISortModel, IUniqueIndexLayer, boolean) after creation to ensure that sorting is working correctly with the groupBy feature.

See Also:
  • Field Details

    • GROUP_BY_OBJECT

      public static final String GROUP_BY_OBJECT
      Label that indicates the shown tree item object as GroupByObject
      See Also:
    • GROUP_BY_COLUMN_PREFIX

      public static final String GROUP_BY_COLUMN_PREFIX
      Label prefix for labels that are added to cells for a group by object.
      See Also:
    • GROUP_BY_SUMMARY

      public static final String GROUP_BY_SUMMARY
      Label that indicates the shown tree item object as GroupByObject and contains a summary value.
      See Also:
    • GROUP_BY_SUMMARY_COLUMN_PREFIX

      public static final String GROUP_BY_SUMMARY_COLUMN_PREFIX
      Label prefix for labels that are added to cells for a group by object summary.
      See Also:
  • Constructor Details

    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor)
      Create a new GroupByDataLayer with the given configuration that:
      • uses the default GroupByExpansionModel which shows all nodes initially expanded
      • has smoothUpdates enabled which leads to showing the summary values that were calculated before until the new value calculation is done
      • uses the default GroupByDataLayerConfiguration
      • does not support groupBy summary values because of the missing IConfigRegistry reference
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor, boolean useDefaultConfiguration)
      Create a new GroupByDataLayer with the given configuration that:
      • uses the default GroupByExpansionModel which shows all nodes initially expanded
      • has smoothUpdates enabled which leads to showing the summary values that were calculated before until the new value calculation is done
      • does not support groupBy summary values because of the missing IConfigRegistry reference
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
      useDefaultConfiguration - true to add the default GroupByDataLayerConfiguration, false for not adding the default configuration.
    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor, IConfigRegistry configRegistry)
      Create a new GroupByDataLayer with the given configuration that:
      • uses the default GroupByExpansionModel which shows all nodes initially expanded
      • has smoothUpdates enabled which leads to showing the summary values that were calculated before until the new value calculation is done
      • uses the default GroupByDataLayerConfiguration
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
      configRegistry - The IConfigRegistry needed to retrieve the groupBy summary configurations.
    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor, IConfigRegistry configRegistry, boolean useDefaultConfiguration)
      Create a new GroupByDataLayer with the given configuration that:
      • uses the default GroupByExpansionModel which shows all nodes initially expanded
      • has smoothUpdates enabled which leads to showing the summary values that were calculated before until the new value calculation is done
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
      configRegistry - The IConfigRegistry needed to retrieve the groupBy summary configurations.
      useDefaultConfiguration - true to add the default GroupByDataLayerConfiguration, false for not adding the default configuration.
    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor, IConfigRegistry configRegistry, boolean smoothUpdates, boolean useDefaultConfiguration)
      Create a new GroupByDataLayer with the given configuration that:
      • uses the default GroupByExpansionModel which shows all nodes initially expanded
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
      configRegistry - The IConfigRegistry needed to retrieve the groupBy summary configurations.
      smoothUpdates - true if the summary values that were calculated before should be returned until the new value calculation is done, false if null should be returned until the calculation is finished.
      useDefaultConfiguration - true to add the default GroupByDataLayerConfiguration, false for not adding the default configuration.
    • GroupByDataLayer

      public GroupByDataLayer(GroupByModel groupByModel, ca.odell.glazedlists.EventList<T> eventList, IColumnAccessor<T> columnAccessor, ca.odell.glazedlists.TreeList.ExpansionModel<Object> expansionModel, IConfigRegistry configRegistry, boolean smoothUpdates, boolean useDefaultConfiguration)
      Create a new GroupByDataLayer with the given configuration.
      Parameters:
      groupByModel - The GroupByModel that is used to define the tree structure based on the groupBy state. Needs to be provided as it is at least shared between the GroupByDataLayer and the GroupByHeaderLayer.
      eventList - The EventList that should be used as source of the internally created TreeList. This should be highest list in the EventList stack in use, e.g. if sorting and filtering is also enabled and the lists are created like this:
                  EventList<T> eventList = GlazedLists.eventList(values);
                  TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
                  SortedList<T> sortedList = new SortedList<>(rowObjectsGlazedList, null);
                  FilterList<T> filterList = new FilterList<>(sortedList);
                  
      the FilterList needs to be used as parameter here.
      columnAccessor - The IColumnAccessor that should be used to access the base row objects.
      expansionModel - The TreeList.ExpansionModel that should be used on the internally created TreeList. If set to null the internal default GroupByExpansionModel will be used that shows all nodes initially expanded.
      configRegistry - The IConfigRegistry needed to retrieve the groupBy summary configurations.
      smoothUpdates - true if the summary values that were calculated before should be returned until the new value calculation is done, false if null should be returned until the calculation is finished.
      useDefaultConfiguration - true to add the default GroupByDataLayerConfiguration, false for not adding the default configuration.
  • Method Details

    • createGroupByTreeFormat

      protected GroupByTreeFormat<T> createGroupByTreeFormat(GroupByModel groupByModel, IColumnAccessor<T> groupByColumnAccessor)
      Parameters:
      groupByModel - The GroupByModel that is used to specify the tree structure.
      groupByColumnAccessor - The IColumnAccessor that is used to access the values in the data model, should be of type GroupByColumnAccessor.
      Returns:
      The GroupByTreeFormat that is used to build the tree structure.
    • initializeTreeComparator

      public void initializeTreeComparator(ISortModel sortModel, IUniqueIndexLayer treeLayer, boolean setDataLayerReference)
      Initialize the Comparator that is used to build the tree structure. Adding all the below information will enable correct sorting of the tree structure taking the summary values and the groupBy values correctly into account.
      Parameters:
      sortModel - The ISortModel that should be set to the IGroupByComparator. Setting the ISortModel enables the usage of the configured Comparator per column on creating the sorted tree structure.
      treeLayer - The IUniqueIndexLayer that should be set to the IGroupByComparator. Typically the TreeLayer and is needed to determine if the sort operation is performed on the tree column. Will only be inspected if a valid ISortModel is set.
      setDataLayerReference - true for setting the GroupByDataLayer reference to this instance to the GroupByComparator, false to set the reference to null. The GroupByDataLayer reference is used in the comparator to be able to sort by summary values. If summary values are not configured or the sorting by summary value is not needed, you should avoid setting the reference.
      See Also:
    • enableFilterSupport

      public void enableFilterSupport(FilterRowDataProvider<T> provider)
      Parameters:
      provider - The FilterRowDataProvider that is used in the composition. Needed to be able to re-apply possible filter states on tree updates.
      Since:
      2.1
    • setComparator

      public void setComparator(IGroupByComparator<T> comparator)
      Parameters:
      comparator - The IGroupByComparator that is necessary to create the sorted tree structure. Can not be null.
    • getSortModel

      public ISortModel getSortModel()
      Returns:
      The ISortModel that is set to the IGroupByComparator.
      Since:
      1.6
      See Also:
    • updateTree

      protected void updateTree()
      Method to update the tree list after filter or TreeList.Format changed. Need this workaround to update the tree list for presentation because of http://java.net/ jira /browse/GLAZEDLISTS-521

      For more information you can also have a look at this discussion: http://glazedlists.1045722.n5.nabble.com/sorting-a-treelist-td4704550. html

    • update

      public void update(Observable o, Object arg)
      Specified by:
      update in interface Observer
    • getTreeRowModel

      public GlazedListTreeRowModel<Object> getTreeRowModel()
      Returns:
      The ITreeRowModel that is responsible to retrieve information and operate on tree items.
    • getTreeList

      public ca.odell.glazedlists.TreeList<Object> getTreeList()
      Returns:
      The TreeList that is created internally by this GroupByDataLayer to enable groupBy.
    • getConfigLabelsByPosition

      public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition)
      Description copied from interface: ILayer
      Returns the config labels for the cell at the given coordinates. Needed to retrieve the corresponding configurations out of the IConfigRegistry.
      Specified by:
      getConfigLabelsByPosition in interface ILayer
      Overrides:
      getConfigLabelsByPosition in class AbstractLayer
      Parameters:
      columnPosition - The column position of the cell.
      rowPosition - The row position of the cell.
      Returns:
      The LabelStack with the config labels for the cell at the given coordinates.
    • getProvidedLabels

      public Collection<String> getProvidedLabels()
      Specified by:
      getProvidedLabels in interface ILayer
      Overrides:
      getProvidedLabels in class AbstractLayer
      Returns:
      The collection of labels that are provided by this layer.
    • getDataValueByPosition

      public Object getDataValueByPosition(int columnPosition, int rowPosition)
      Description copied from interface: ILayer
      Returns the data value for the cell at the given coordinates.
      Specified by:
      getDataValueByPosition in interface ILayer
      Overrides:
      getDataValueByPosition in class DataLayer
      Parameters:
      columnPosition - The column position of the cell.
      rowPosition - The row position of the cell.
      Returns:
      The data value for the cell at the given coordinates.
    • getDataValueByPosition

      public Object getDataValueByPosition(int columnPosition, int rowPosition, LabelStack labelStack, boolean calculateInBackground)
      This method is used to retrieve a data value of an ILayerCell. It is intended to be used for conditional formatting. It allows to specify the LabelStack and to disable background calculation processing, since the conditional formatting needs the summary value without a delay.
      Parameters:
      columnPosition - The column position of the cell whose data value is requested.
      rowPosition - The row position of the cell whose data value is requested.
      labelStack - The LabelStack of the cell whose data value is requested. Needed to retrieve a possible existing IGroupBySummaryProvider.
      calculateInBackground - true to calculate the summary value in the background, false if the calculation should be processed in the UI thread.
      Returns:
      The data value for the ILayerCell at the given coordinates.
    • getGroupBySummaryProvider

      public IGroupBySummaryProvider<T> getGroupBySummaryProvider(LabelStack labelStack)
    • handleLayerEvent

      public void handleLayerEvent(ILayerEvent event)
      Description copied from class: AbstractLayer
      Handle layer event notification. Convert it to your context and propagate UP. If you override this method you MUST NOT FORGET to raise the event up the layer stack by calling super.fireLayerEvent(event) - unless you plan to eat the event yourself.
      Specified by:
      handleLayerEvent in interface ILayerListener
      Overrides:
      handleLayerEvent in class AbstractLayer
      Parameters:
      event - the event
    • clearCache

      public void clearCache()
      Clear the internal cache to trigger new calculations.

      Usually it is not necessary to call this method manually. But for certain use cases it might be useful, e.g. changing the summary provider implementation at runtime.

      See Also:
    • killCache

      public void killCache()
      Clears all values in the internal cache to trigger new calculations. This will also clear all values in the cache copy and will result in rendering like there was never a summary value calculated before.

      Usually it is not necessary to call this method manually. But for certain use cases it might be useful, e.g. changing the summary provider implementation at runtime.

      See Also:
    • doCommand

      public boolean doCommand(ILayerCommand command)
      Description copied from interface: ILayer
      Opportunity to respond to a command as it flows down the stack. If the layer is not interested in the command it should allow the command to keep traveling down the stack.

      Note: Before the layer can process a command it must convert the command to its local coordinates using ILayerCommand.convertToTargetLayer(ILayer)

      Specified by:
      doCommand in interface ILayer
      Overrides:
      doCommand in class DataLayer
      Parameters:
      command - The command to execute.
      Returns:
      true if the command has been handled and was therefore consumed, false otherwise.
    • getValueCache

      public ICalculatedValueCache getValueCache()
      Returns:
      The ICalculatedValueCache that contains the summary values and performs summary calculation in background processes if necessary.
    • setValueCache

      public void setValueCache(ICalculatedValueCache valueCache)
      Set the ICalculatedValueCache that should be used internally to calculate the summary values in a background thread and cache the results.

      Note: By default the CalculatedValueCache is used. Be sure you know what you are doing when you are trying to exchange the implementation.

      Parameters:
      valueCache - The ICalculatedValueCache that contains the summary values and performs summary calculation in background processes if necessary.
    • getItemsInGroup

      public List<T> getItemsInGroup(GroupByObject group)
      Get the list of the items in a group. Used for example to calculate the group summary values or group item count.

      Note: This method returns a new list and is therefore thread safe.

      Parameters:
      group - The GroupByObject for which the children should be retrieved.
      Returns:
      The list of items in the group specified by the given GroupByObject
      Since:
      1.5
    • getGroupDescriptorMatcher

      protected ca.odell.glazedlists.matchers.Matcher<T> getGroupDescriptorMatcher(GroupByObject group, IColumnAccessor<T> columnAccessor)
      Parameters:
      group - The GroupByObject for which the children should be retrieved.
      columnAccessor - The IColumnAccessor that is used to retrieve column value of an element.
      Returns:
      The Matcher that is used to identify the children of a GroupByObject
      See Also: