use of org.eclipse.nebula.widgets.nattable.layer.LabelStack in project nebula.widgets.nattable by eclipse.
the class GroupByDataLayer method doCommand.
@Override
public boolean doCommand(ILayerCommand command) {
if (command instanceof CalculateSummaryRowValuesCommand) {
// summary values
for (int i = 0; i < getRowCount(); i++) {
if (this.treeData.getDataAtIndex(i) instanceof GroupByObject) {
for (int j = 0; j < getColumnCount(); j++) {
LabelStack labelStack = getConfigLabelsByPosition(j, i);
final IGroupBySummaryProvider<T> summaryProvider = getGroupBySummaryProvider(labelStack);
if (summaryProvider != null) {
GroupByObject groupByObject = (GroupByObject) this.treeData.getDataAtIndex(i);
final List<T> children = getItemsInGroup(groupByObject);
final int col = j;
this.valueCache.getCalculatedValue(j, i, new GroupByValueCacheKey(j, i, groupByObject), false, new ICalculator() {
@Override
public Object executeCalculation() {
return summaryProvider.summarize(col, children);
}
});
}
}
}
}
// we do not return true here, as there might be other layers
// involved in the composition that also need to calculate the
// summary values immediately
} else if (command instanceof DisposeResourcesCommand) {
// ensure to clear the caches to avoid memory leaks
this.treeFormat.clearComparatorCache();
this.valueCache.killCache();
this.valueCache.dispose();
}
return super.doCommand(command);
}
use of org.eclipse.nebula.widgets.nattable.layer.LabelStack in project nebula.widgets.nattable by eclipse.
the class GroupByDragMode method mouseUp.
@Override
public void mouseUp(NatTable natTable, MouseEvent event) {
LabelStack regionLabels = natTable.getRegionLabelsByXY(event.x, event.y);
if (regionLabels != null && regionLabels.hasLabel(GroupByHeaderLayer.GROUP_BY_REGION) && this.selectedColumnIndex != -1) {
natTable.doCommand(new GroupByColumnIndexCommand(this.selectedColumnIndex));
this.selectedColumnIndex = -1;
}
}
use of org.eclipse.nebula.widgets.nattable.layer.LabelStack in project nebula.widgets.nattable by eclipse.
the class GroupByComparator method getSummaryValueFromCache.
/**
* Returns the cached summary value for the given {@link GroupByObject} and
* column index. If there is no cache information yet, it will be build.
*
* @param groupBy
* The {@link GroupByObject} for which the cache information is
* requested.
* @param columnIndex
* The column for which the cache information is requested.
* @return The summary value for the given {@link GroupByObject} and column
* index or <code>null</code> in case there is no
* {@link GroupByDataLayer} configured in for this
* {@link GroupByComparator}.
*/
protected Object getSummaryValueFromCache(GroupByObject groupBy, int columnIndex) {
Object columnCache = null;
// set
if (this.dataLayer != null) {
// check if a cache object is already there
GroupByObjectValueCache cache = this.groupByObjectComparatorCache.get(groupBy);
if (cache == null) {
cache = new GroupByObjectValueCache();
this.groupByObjectComparatorCache.put(groupBy, cache);
}
// check if the cache object already contains information about the
// column
columnCache = cache.valueCache.get(columnIndex);
if (columnCache == null) {
// This is the performance bottleneck that is the reason for the
// caching!
int rowIndex = this.dataLayer.getTreeList().indexOf(groupBy);
if (rowIndex >= 0) {
LabelStack labelStack = this.dataLayer.getConfigLabelsByPosition(columnIndex, rowIndex);
IGroupBySummaryProvider<T> provider = this.dataLayer.getGroupBySummaryProvider(labelStack);
boolean isSummaryColumn = provider != null;
this.summaryColumnCache.put(columnIndex, isSummaryColumn);
if (isSummaryColumn) {
/*
* Special Case: If a summary column is grouped, the
* summary value is the same as the GroupByObject value.
* In that case the roundtrip using the summary provider
* is not necessary and we should improve the
* performance if the sorting should be applied for that
* column.
*/
// the descriptor map needs to be ordered
// (LinkedHashMap) and we need to find the last one in
// the order to check if a summary column was used for
// grouping
Entry<Integer, Object> last = null;
for (Entry<Integer, Object> entry : groupBy.getDescriptor().entrySet()) {
last = entry;
}
if (last != null && last.getKey() == columnIndex) {
columnCache = groupBy.getValue();
} else {
columnCache = this.dataLayer.getDataValueByPosition(columnIndex, rowIndex, labelStack, false);
}
cache.valueCache.put(columnIndex, columnCache);
}
}
}
} else {
this.summaryColumnCache.put(columnIndex, false);
}
return columnCache;
}
use of org.eclipse.nebula.widgets.nattable.layer.LabelStack in project nebula.widgets.nattable by eclipse.
the class GroupByDataLayer method getConfigLabelsByPosition.
@Override
public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
if (this.treeData.getDataAtIndex(getRowIndexByPosition(rowPosition)) instanceof GroupByObject) {
LabelStack configLabels = new LabelStack();
configLabels.addLabel(GROUP_BY_COLUMN_PREFIX + columnPosition);
configLabels.addLabel(GROUP_BY_OBJECT);
if (this.getConfigLabelAccumulator() != null) {
this.getConfigLabelAccumulator().accumulateConfigLabels(configLabels, columnPosition, rowPosition);
}
if (this.getRegionName() != null) {
configLabels.addLabel(this.getRegionName());
}
if (getGroupBySummaryProvider(configLabels) != null) {
configLabels.addLabelOnTop(GROUP_BY_SUMMARY);
configLabels.addLabelOnTop(GROUP_BY_SUMMARY_COLUMN_PREFIX + columnPosition);
}
return configLabels;
}
return super.getConfigLabelsByPosition(columnPosition, rowPosition);
}
use of org.eclipse.nebula.widgets.nattable.layer.LabelStack in project nebula.widgets.nattable by eclipse.
the class GroupByDisplayConverter method getDisplayValue.
/**
* Searches for the {@link IDisplayConverter} to use for the given
* {@link ILayerCell} and converts the given canonical value to the display
* value using the found converter.
*
* @param cell
* The {@link ILayerCell} for which the display value is asked.
* @param configRegistry
* The {@link ConfigRegistry} necessary to retrieve the
* {@link IDisplayConverter}.
* @param canonicalValue
* The canonical value to convert.
* @return The canonical value converted to the display value.
*/
protected Object getDisplayValue(ILayerCell cell, IConfigRegistry configRegistry, Object canonicalValue) {
IDisplayConverter converter = null;
Object canonical = canonicalValue;
if (this.wrappedConverters.containsKey(cell.getColumnIndex())) {
converter = this.wrappedConverters.get(cell.getColumnIndex());
} else if (canonicalValue instanceof GroupByObject) {
GroupByObject groupByObject = (GroupByObject) canonicalValue;
int lastGroupingIndex = -1;
for (Map.Entry<Integer, Object> groupEntry : groupByObject.getDescriptor().entrySet()) {
lastGroupingIndex = groupEntry.getKey();
}
if (lastGroupingIndex >= 0) {
canonical = ((GroupByObject) canonicalValue).getValue();
// cache
if (this.converterCache.containsKey(lastGroupingIndex)) {
converter = this.converterCache.get(lastGroupingIndex);
} else {
int rowPosition = cell.getRowPosition() + 1;
LabelStack stackBelow = this.groupByDataLayer.getConfigLabelsByPosition(lastGroupingIndex, rowPosition);
while (stackBelow.hasLabel(GroupByDataLayer.GROUP_BY_OBJECT)) {
stackBelow = this.groupByDataLayer.getConfigLabelsByPosition(lastGroupingIndex, ++rowPosition);
}
converter = configRegistry.getConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, DisplayMode.NORMAL, stackBelow.getLabels());
// this converter additionally
if (!this.converterCache.containsKey(lastGroupingIndex)) {
this.converterCache.put(lastGroupingIndex, converter);
}
}
}
} else {
// create a copy of the label stack to avoid finding this
// converter again
// Note: this displayConverter needs to be registered for the
// GroupByDataLayer.GROUP_BY_OBJECT label
List<String> labels = new ArrayList<String>(cell.getConfigLabels().getLabels());
labels.remove(GroupByDataLayer.GROUP_BY_OBJECT);
converter = configRegistry.getConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, DisplayMode.NORMAL, labels);
if (converter == this) {
// we found ourself again, so let's skip this
converter = null;
}
}
if (converter == null) {
converter = new DefaultDisplayConverter();
}
return converter.canonicalToDisplayValue(cell, configRegistry, canonical);
}
Aggregations