Summary row

You can add a summary row to your NatTable easily by adding and configuring the SummaryRowLayer.

Summary Row Example

The Creating_a_summary_row and CalculatingGridExample examples are the best places to look at.

Adding the SummaryRowLayer to the body layer stack

To add a summary row to your NatTable, you have to add the SummaryRowLayer to your body layer stack. As it should deal directly to the data shown in the NatTable, it should be added to the body layer close to the DataLayer. As with all layers this can easily be done with the following code snippet:

IConfigRegistry configRegistry = new ConfigRegistry(); IUniqueIndexLayer dataLayer = new DataLayer(myDataProvider); // Plug in the SummaryRowLayer IUniqueIndexLayer summaryRowLayer = new SummaryRowLayer(dataLayer, configRegistry, false); ViewportLayer viewportLayer = new ViewportLayer(summaryRowLayer);

Snippet from Creating_a_summary_row example

Note that the SummaryRowLayer needs the ConfigRegistry to access the summary row specific configurations.

Configuring the summary data

The next step on adding a summary row to a NatTable is to configure the content that should be showed within the summary row. This is done by ISummaryProvider that need to be configured via ConfigRegistry.

NatTable comes with three default ISummaryProvider

  • ISummaryProvider.DEFAULT
    always returns the String ...
  • ISummaryProvider.NONE
    always returns null which skips calls to the ISummaryProvider and is a performance tweak
  • SummationSummaryProvider
    needs the body data provider so it can iterate over all values for the column it is configured to and summarize all the number values to a resulting float value
Creating your own ISummaryProvider is quite easy. The following snippet shows how to implement one to calculate the average value instead of the sum.
class AverageSummaryProvider implements ISummaryProvider { public Object summarize(int columnIndex) { int total = 0; int rowCount = myDataProvider.getRowCount(); for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) { Object dataValue = myDataProvider.getDataValue(columnIndex, rowIndex); total = total + Integer.parseInt(dataValue.toString()); } return "Average: " + total / rowCount; } }

Snippet from Creating_a_summary_row example

To be able to configure the SummaryRowLayer in detail, it introduces two new labels for which the specific configurations can be added:

  • SummaryRowLayer#DEFAULT_SUMMARY_ROW_CONFIG_LABEL to all cells in the row
  • SummaryRowLayer#DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX + column index per column

There is a DefaultSummaryRowConfiguration to configure the style and the summary formulas of the summary row. You can extend that or create your own configuration. In this configuration you should add your ISummaryProvider as you like the SummaryRowLayer to be configured.

// Default summary provider configRegistry.registerConfigAttribute( SummaryRowConfigAttributes.SUMMARY_PROVIDER, new SummationSummaryProvider(myDataProvider), DisplayMode.NORMAL, SummaryRowLayer.DEFAULT_SUMMARY_ROW_CONFIG_LABEL); // Average summary provider for column index 2 configRegistry.registerConfigAttribute( SummaryRowConfigAttributes.SUMMARY_PROVIDER, new AverageSummaryProvider(), DisplayMode.NORMAL, SummaryRowLayer.DEFAULT_SUMMARY_COLUMN_CONFIG_LABEL_PREFIX + 2);

Snippet from MySummaryRowConfig of the Creating_a_summary_row example

Summary row label in the row header

To reflect the summary row within the row header of a grid, you should consider using the DefaultSummaryRowHeaderDataProvider to create the DataLayer of your DefaultSummaryRowHeaderDataProvider or something custom that looks like it. Using this the row header will show incrementing line numbers for all data rows and by default the word Summary for the summary row. The DefaultSummaryRowHeaderDataProvider also has a constructor that accepts a parameter that allows you to specify your own row header label for the summary row.

IDataProvider rowHeaderDataProvider = new DefaultSummaryRowHeaderDataProvider( bodyLayer.getDataLayer().getDataProvider(), "\u2211"); ILayer rowHeaderLayer = new RowHeaderLayer( new DefaultRowHeaderDataLayer(rowHeaderDataProvider), bodyLayer, selectionLayer);

Snippet from CalculatingGridLayer of the CalculatingGridExample