aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Pauzies2013-11-20 08:24:57 (EST)
committerDirk Fauth2013-11-20 08:24:57 (EST)
commita499389a8061cefc377f1aa74e415803d144da79 (patch)
treefa1fa1500f6a9722d992dd77987b2feb9a297132
parente64bd10f499e040d5797221381389db40ca49555 (diff)
downloadorg.eclipse.nebula.widgets.nattable-a499389a8061cefc377f1aa74e415803d144da79.zip
org.eclipse.nebula.widgets.nattable-a499389a8061cefc377f1aa74e415803d144da79.tar.gz
org.eclipse.nebula.widgets.nattable-a499389a8061cefc377f1aa74e415803d144da79.tar.bz2
Bug 416095 - Initial contribution for summary values in the groupBy
feature Signed-off-by: Alexandre Pauzies <alexandre@pauzies.com>
-rw-r--r--org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/ITreeData.java161
-rw-r--r--org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_150_Column_and_row_grouping/_200_Group_by.java60
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByColumnAccessor.java88
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java68
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayerConfiguration.java86
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByObject.java209
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByTreeFormat.java312
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryColumnAccessor.java57
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryConfigAttributes.java11
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/IGroupBySummaryProvider.java14
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/SummationGroupBySummaryProvider.java27
-rw-r--r--org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/tree/GlazedListTreeData.java64
13 files changed, 697 insertions, 461 deletions
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/ITreeData.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/ITreeData.java
index 6b06522..12a2d11 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/ITreeData.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/ITreeData.java
@@ -1,76 +1,85 @@
-/*******************************************************************************
- * Copyright (c) 2012 Original authors and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Original authors and others - initial API and implementation
- ******************************************************************************/
-package org.eclipse.nebula.widgets.nattable.tree;
-
-import java.util.List;
-
-
-
-public interface ITreeData <T> {
-
- String formatDataForDepth(int depth, T object);
-
- String formatDataForDepth(int depth, int index);
-
- int getDepthOfData(T object);
-
- int getDepthOfData(int index);
-
- /**
- * @param index The index for which the corresponding object in the tree
- * structure is requested.
- * @return The object at the given index in the tree structure.
- */
- T getDataAtIndex(int index);
-
- /**
- * @param child The child whose index is requested.
- * @return The index of the given child object in the tree structure.
- */
- int indexOf(T child);
-
- /**
- * @param object The object which should be checked for children.
- * @return <code>true</code> if the object has children in the tree structure,
- * <code>false</code> if it is a leaf.
- */
- boolean hasChildren(T object);
-
- /**
- * @param index The index of the object in the tree structure which should be checked for children.
- * @return <code>true</code> if the object has children in the tree structure,
- * <code>false</code> if it is a leaf.
- */
- boolean hasChildren(int index);
-
- /**
- * Return the child objects below the given object if the object
- * is a tree node. It will only return the direct children and will
- * not search for sub children.
- * @param object The object whose children are requested.
- * @return The children of the given object.
- */
- List<T> getChildren(T object);
-
- /**
- * Return the child objects below the object at the given index if the object
- * is a tree node. It will only return the direct children and will
- * not search for sub children.
- * @param index The index of the object whose children are requested.
- * @return The children of the object at the given index.
- */
- List<T> getChildren(int index);
-
- /**
- * @return The root elements of the tree structure.
- */
- List<T> getRoots();
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Original authors and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Original authors and others - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.tree;
+
+import java.util.List;
+
+
+
+public interface ITreeData <T> {
+
+ String formatDataForDepth(int depth, T object);
+
+ String formatDataForDepth(int depth, int index);
+
+ int getDepthOfData(T object);
+
+ int getDepthOfData(int index);
+
+ /**
+ * @param index The index for which the corresponding object in the tree
+ * structure is requested.
+ * @return The object at the given index in the tree structure.
+ */
+ T getDataAtIndex(int index);
+
+ /**
+ * @param child The child whose index is requested.
+ * @return The index of the given child object in the tree structure.
+ */
+ int indexOf(T child);
+
+ /**
+ * @param object The object which should be checked for children.
+ * @return <code>true</code> if the object has children in the tree structure,
+ * <code>false</code> if it is a leaf.
+ */
+ boolean hasChildren(T object);
+
+ /**
+ * @param index The index of the object in the tree structure which should be checked for children.
+ * @return <code>true</code> if the object has children in the tree structure,
+ * <code>false</code> if it is a leaf.
+ */
+ boolean hasChildren(int index);
+
+ /**
+ * Return the child objects below the given object if the object
+ * is a tree node. It will only return the direct children and will
+ * not search for sub children.
+ * @param object The object whose children are requested.
+ * @return The children of the given object.
+ */
+ List<T> getChildren(T object);
+
+ /**
+ * Return the child objects below the given object if the object
+ * is a tree node.
+ * @param object The object whose children are requested.
+ * @param fullDepth to return only direct children or search for sub children
+ * @return The children of the given object.
+ */
+ List<T> getChildren(T object, boolean fullDepth);
+
+ /**
+ * Return the child objects below the object at the given index if the object
+ * is a tree node. It will only return the direct children and will
+ * not search for sub children.
+ * @param index The index of the object whose children are requested.
+ * @return The children of the object at the given index.
+ */
+ List<T> getChildren(int index);
+
+ /**
+ * @return The root elements of the tree structure.
+ */
+ List<T> getRoots();
+}
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_150_Column_and_row_grouping/_200_Group_by.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_150_Column_and_row_grouping/_200_Group_by.java
index 1229be9..fe4e1d1 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_150_Column_and_row_grouping/_200_Group_by.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_150_Column_and_row_grouping/_200_Group_by.java
@@ -12,8 +12,8 @@ package org.eclipse.nebula.widgets.nattable.examples.examples._150_Column_and_ro
import java.util.Map;
-
import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
@@ -24,6 +24,8 @@ import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupBy
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByHeaderLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByHeaderMenuConfiguration;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByModel;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary.GroupBySummaryConfigAttributes;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary.SummationGroupBySummaryProvider;
import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer;
import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
@@ -41,6 +43,7 @@ import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.test.fixture.data.RowDataFixture;
import org.eclipse.nebula.widgets.nattable.test.fixture.data.RowDataListFixture;
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
@@ -64,7 +67,7 @@ public class _200_Group_by extends AbstractNatExample {
public static void main(String[] args) {
StandaloneNatExampleRunner.run(800, 400, new _200_Group_by());
}
-
+
@Override
public String getDescription() {
return
@@ -72,36 +75,41 @@ public class _200_Group_by extends AbstractNatExample {
"If you drag a column header into this region, rows in the grid will be grouped by this column.\n" +
"If you right-click on the names in the Group By region, you can ungroup by the clicked column.";
}
-
+
public Control createExampleControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(1, false));
-
+
// Underlying data source
EventList<RowDataFixture> eventList = GlazedLists.eventList(RowDataListFixture.getList(200));
String[] propertyNames = RowDataListFixture.getPropertyNames();
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
IColumnPropertyAccessor<RowDataFixture> reflectiveColumnPropertyAccessor = new ReflectiveColumnPropertyAccessor<RowDataFixture>(propertyNames);
-
+
GroupByModel groupByModel = new GroupByModel();
-
- GroupByDataLayer<RowDataFixture> bodyDataLayer = new GroupByDataLayer<RowDataFixture>(groupByModel, eventList, reflectiveColumnPropertyAccessor);
-
+
+ // Summary
+ ConfigRegistry configRegistry = new ConfigRegistry();
+ configRegistry.registerConfigAttribute(GroupBySummaryConfigAttributes.GROUP_BY_SUMMARY_PROVIDER,
+ new SummationGroupBySummaryProvider<RowDataFixture>(reflectiveColumnPropertyAccessor),
+ DisplayMode.NORMAL, GroupByDataLayer.SUMMARIZE);
+
+ GroupByDataLayer<RowDataFixture> bodyDataLayer = new GroupByDataLayer<RowDataFixture>(groupByModel, eventList,
+ reflectiveColumnPropertyAccessor, configRegistry);
+
// Body layer
ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(bodyDataLayer);
ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
SelectionLayer selectionLayer = new SelectionLayer(columnHideShowLayer);
-
+
TreeLayer treeLayer = new TreeLayer(selectionLayer, bodyDataLayer.getTreeRowModel());
-
-
+
FreezeLayer freeze = new FreezeLayer(treeLayer);
-
+
ViewportLayer viewportLayer = new ViewportLayer(treeLayer);
-
+
CompositeFreezeLayer compFreeze = new CompositeFreezeLayer(freeze, viewportLayer, selectionLayer);
-
-
+
// Column header layer
final IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
final DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
@@ -111,11 +119,15 @@ public class _200_Group_by extends AbstractNatExample {
ColumnOverrideLabelAccumulator labelAccumulator = new ColumnOverrideLabelAccumulator(columnHeaderDataLayer);
columnHeaderDataLayer.setConfigLabelAccumulator(labelAccumulator);
+ bodyDataLayer.setConfigLabelAccumulator(labelAccumulator);
// Register labels
labelAccumulator.registerColumnOverrides(
- RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.RATING_PROP_NAME),
- "CUSTOM_COMPARATOR_LABEL");
+ RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.RATING_PROP_NAME),
+ "CUSTOM_COMPARATOR_LABEL");
+ labelAccumulator.registerColumnOverrides(
+ RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.LOT_SIZE_PROP_NAME),
+ GroupByDataLayer.SUMMARIZE);
// Row header layer
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataLayer.getDataProvider());
@@ -133,22 +145,24 @@ public class _200_Group_by extends AbstractNatExample {
columnHeaderLayer,
rowHeaderLayer,
cornerLayer, false);
-
+
CompositeLayer compositeGridLayer = new CompositeLayer(1, 2);
final GroupByHeaderLayer groupByHeaderLayer = new GroupByHeaderLayer(groupByModel, gridLayer, columnHeaderDataProvider);
compositeGridLayer.setChildLayer(GroupByHeaderLayer.GROUP_BY_REGION, groupByHeaderLayer, 0, 0);
compositeGridLayer.setChildLayer("Grid", gridLayer, 0, 1);
-
+
NatTable natTable = new NatTable(comp, compositeGridLayer, false);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
natTable.addConfiguration(new GroupByHeaderMenuConfiguration(natTable, groupByHeaderLayer));
natTable.addConfiguration(new HeaderMenuConfiguration(natTable));
natTable.addConfiguration(new DebugMenuConfiguration(natTable));
-
+
+ natTable.setConfigRegistry(configRegistry);
+
natTable.configure();
-
+
natTable.setLayoutData(new GridData(GridData.FILL_BOTH));
-
+
Button button = new Button(comp, SWT.NONE);
button.setText("Toggle Group By Header");
button.addMouseListener(new MouseAdapter() {
@@ -156,7 +170,7 @@ public class _200_Group_by extends AbstractNatExample {
groupByHeaderLayer.setVisible(!groupByHeaderLayer.isVisible());
}
});
-
+
return comp;
}
}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
index cdf75ef..bf78528 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@ Export-Package: org.eclipse.nebula.widgets.nattable.extension.glazedlists,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.action,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.command,
+ org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree
Import-Package: ca.odell.glazedlists,
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByColumnAccessor.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByColumnAccessor.java
index 66cf15f..ed4c705 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByColumnAccessor.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByColumnAccessor.java
@@ -1,44 +1,44 @@
-/*******************************************************************************
- * Copyright (c) 2012 Original authors and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Original authors and others - initial API and implementation
- ******************************************************************************/
-package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
-
-import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
-
-public class GroupByColumnAccessor<T> implements IColumnAccessor<Object> {
-
- private final IColumnAccessor<T> columnAccessor;
-
- public GroupByColumnAccessor(IColumnAccessor<T> columnAccessor) {
- this.columnAccessor = columnAccessor;
- }
-
- public Object getDataValue(Object rowObject, int columnIndex) {
- if (rowObject instanceof GroupByObject) {
- GroupByObject groupByObject = (GroupByObject) rowObject;
- return groupByObject.getValue();
- } else {
- return columnAccessor.getDataValue((T) rowObject, columnIndex);
- }
- }
-
- public void setDataValue(Object rowObject, int columnIndex, Object newValue) {
- if (rowObject instanceof GroupByObject) {
- // do nothing
- } else {
- columnAccessor.setDataValue((T) rowObject, columnIndex, newValue);
- }
- }
-
- public int getColumnCount() {
- return columnAccessor.getColumnCount();
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Original authors and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Original authors and others - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
+
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+
+public class GroupByColumnAccessor<T> implements IColumnAccessor<Object> {
+
+ protected final IColumnAccessor<T> columnAccessor;
+
+ public GroupByColumnAccessor(IColumnAccessor<T> columnAccessor) {
+ this.columnAccessor = columnAccessor;
+ }
+
+ public Object getDataValue(Object rowObject, int columnIndex) {
+ if (rowObject instanceof GroupByObject) {
+ GroupByObject groupByObject = (GroupByObject) rowObject;
+ return groupByObject.getValue();
+ } else {
+ return columnAccessor.getDataValue((T) rowObject, columnIndex);
+ }
+ }
+
+ public void setDataValue(Object rowObject, int columnIndex, Object newValue) {
+ if (rowObject instanceof GroupByObject) {
+ // do nothing
+ } else {
+ columnAccessor.setDataValue((T) rowObject, columnIndex, newValue);
+ }
+ }
+
+ public int getColumnCount() {
+ return columnAccessor.getColumnCount();
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
index e5bc51d..b9809b5 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayer.java
@@ -10,17 +10,21 @@
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
+import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsDataProvider;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary.GroupBySummaryColumnAccessor;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeData;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeRowModel;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.event.RowStructuralRefreshEvent;
+import org.eclipse.nebula.widgets.nattable.sort.ISortModel;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.TreeList;
@@ -32,6 +36,10 @@ public class GroupByDataLayer<T> extends DataLayer implements Observer {
*/
public static final String GROUP_BY_OBJECT = "GROUP_BY_OBJECT"; //$NON-NLS-1$
/**
+ * Label that indicates the shown tree item object should summarize its children
+ */
+ public static final String SUMMARIZE = "SUMMARIZE"; //$NON-NLS-1$
+ /**
* The underlying base EventList.
*/
private final EventList<T> eventList;
@@ -47,25 +55,44 @@ public class GroupByDataLayer<T> extends DataLayer implements Observer {
* The TreeList that is created internally by this GroupByDataLayer to enable groupBy.
*/
private final TreeList<Object> treeList;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
+
+ private final GroupByTreeFormat<T> treeFormat;
+
+ /** Map the group to a dynamic list of group elements */
+
public GroupByDataLayer(GroupByModel groupByModel, EventList<T> eventList, IColumnAccessor<T> columnAccessor) {
+ this(groupByModel, eventList, columnAccessor, null);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public GroupByDataLayer(GroupByModel groupByModel, EventList<T> eventList, IColumnAccessor<T> columnAccessor,
+ IConfigRegistry configRegistry) {
this.eventList = eventList;
-
+
groupByModel.addObserver(this);
-
- TreeList.Format<Object> treeFormat = new GroupByTreeFormat<T>(groupByModel, columnAccessor);
+
+ IColumnAccessor<T> groupByColumnAccessor = null;
+ if (configRegistry != null) {
+ groupByColumnAccessor = new GroupBySummaryColumnAccessor(columnAccessor, configRegistry, this);
+ } else {
+ groupByColumnAccessor = new GroupByColumnAccessor(columnAccessor);
+ }
+
+ treeFormat = new GroupByTreeFormat<T>(groupByModel, groupByColumnAccessor);
this.treeList = new TreeList(eventList, treeFormat, new GroupByExpansionModel());
-
+
treeData = new GlazedListTreeData<Object>(getTreeList());
treeRowModel = new GlazedListTreeRowModel<Object>(treeData);
-
- IColumnAccessor<Object> groupByColumnAccessor = new GroupByColumnAccessor<T>(columnAccessor);
- setDataProvider(new GlazedListsDataProvider<Object>(getTreeList(), groupByColumnAccessor));
-
+
+ setDataProvider(new GlazedListsDataProvider<Object>(getTreeList(), (IColumnAccessor<Object>) groupByColumnAccessor));
+
addConfiguration(new GroupByDataLayerConfiguration());
}
-
+
+ public void setSortModel(ISortModel model) {
+ treeFormat.setSortModel(model);
+ }
+
/**
* Method to update the tree list after filter or TreeList.Format changed.
* Need this workaround to update the tree list for presentation because of
@@ -97,14 +124,14 @@ public class GroupByDataLayer<T> extends DataLayer implements Observer {
public GlazedListTreeRowModel<Object> getTreeRowModel() {
return treeRowModel;
}
-
+
/**
* @return The TreeList that is created internally by this GroupByDataLayer to enable groupBy.
*/
public TreeList<Object> getTreeList() {
return treeList;
}
-
+
@Override
public LabelStack getConfigLabelsByPosition(int columnPosition, int rowPosition) {
LabelStack configLabels = super.getConfigLabelsByPosition(columnPosition, rowPosition);
@@ -123,7 +150,7 @@ public class GroupByDataLayer<T> extends DataLayer implements Observer {
* internally.
*
* @see http://publicobject.com/glazedlists/glazedlists-1.8.0/api/ca/odell/
- * glazedlists/TreeList.ExpansionModel.html
+ * glazedlists/TreeList.ExpansionModel.html
*/
private class GroupByExpansionModel implements TreeList.ExpansionModel<Object> {
/**
@@ -144,4 +171,17 @@ public class GroupByDataLayer<T> extends DataLayer implements Observer {
}
}
+ @SuppressWarnings("unchecked")
+ public List<T> getElementsInGroup(GroupByObject groupDescriptor) {
+ List<T> children = new ArrayList<T>();
+ for (Object o : treeData.getChildren(groupDescriptor, true)) {
+ if (o instanceof GroupByObject) {
+ // do nothing
+ } else {
+ children.add((T) o);
+ }
+ }
+ return children;
+ }
+
}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayerConfiguration.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayerConfiguration.java
index 6e9d978..c4d10c7 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayerConfiguration.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByDataLayerConfiguration.java
@@ -1,43 +1,43 @@
-/*******************************************************************************
- * Copyright (c) 2012 Edwin Park and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Edwin Park - initial API and implementation
- ******************************************************************************/
-package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
-
-import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
-import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
-import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
-import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
-import org.eclipse.nebula.widgets.nattable.painter.cell.BackgroundPainter;
-import org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter;
-import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
-import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
-import org.eclipse.swt.graphics.GC;
-
-public class GroupByDataLayerConfiguration extends AbstractRegistryConfiguration {
-
- public void configureRegistry(IConfigRegistry configRegistry) {
- configRegistry.registerConfigAttribute(
- CellConfigAttributes.CELL_PAINTER,
- new BackgroundPainter(new TextPainter() {
- @Override
- protected String getTextToDisplay(ILayerCell cell, GC gc, int availableLength, String text) {
- if (cell.getConfigLabels().getLabels().contains(TreeLayer.TREE_COLUMN_CELL)) {
- return super.getTextToDisplay(cell, gc, availableLength, text);
- } else {
- return ""; //$NON-NLS-1$
- }
- }
- }),
- DisplayMode.NORMAL,
- GroupByDataLayer.GROUP_BY_OBJECT
- );
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012 Edwin Park and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Edwin Park - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
+
+import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
+import org.eclipse.nebula.widgets.nattable.painter.cell.BackgroundPainter;
+import org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter;
+import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
+import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
+import org.eclipse.swt.graphics.GC;
+
+public class GroupByDataLayerConfiguration extends AbstractRegistryConfiguration {
+
+ public void configureRegistry(IConfigRegistry configRegistry) {
+ configRegistry.registerConfigAttribute(
+ CellConfigAttributes.CELL_PAINTER,
+ new BackgroundPainter(new TextPainter() {
+ @Override
+ protected String getTextToDisplay(ILayerCell cell, GC gc, int availableLength, String text) {
+ if (cell.getConfigLabels().hasLabel(TreeLayer.TREE_COLUMN_CELL) || cell.getConfigLabels().hasLabel(GroupByDataLayer.SUMMARIZE)) {
+ return super.getTextToDisplay(cell, gc, availableLength, text);
+ } else {
+ return ""; //$NON-NLS-1$
+ }
+ }
+ }),
+ DisplayMode.NORMAL,
+ GroupByDataLayer.GROUP_BY_OBJECT
+ );
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByObject.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByObject.java
index f3a9b04..f9d9563 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByObject.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByObject.java
@@ -1,105 +1,104 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Original authors and others - initial API and implementation
- ******************************************************************************/
-package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
-
-import org.eclipse.nebula.widgets.nattable.config.DefaultComparator;
-
-/**
- * This class is used to add tree items that are added to the tree path for grouping purposes.
- * Contains the value that is used for grouping and the grouping index to ensure the correct
- * ordering.
- */
-public class GroupByObject implements Comparable<GroupByObject> {
-
- /**
- * The order index of the grouping.
- */
- private final Integer groupByIndex;
- /**
- * The value that is used for grouping.
- */
- private final Object value;
-
- /**
- * @param groupByIndex The order index of the grouping.
- * @param value The value that is used for grouping.
- */
- public GroupByObject(int groupByIndex, Object value) {
- this.groupByIndex = groupByIndex;
- this.value = value;
- }
-
- /**
- * @return The order index of the grouping.
- */
- public int getGroupByIndex() {
- return groupByIndex;
- }
-
- /**
- * @return The value that is used for grouping.
- */
- public Object getValue() {
- return value;
- }
-
- @Override
- public String toString() {
- //Without adjusting a lot of API and adding dependencies to the DataLayer and the ConfigRegistry
- //we can not get the IDataConverter here. It might be solvable with the next generation because
- //we can then inject the necessary values. Until then you should consider implementing toString()
- return value.toString();
- }
-
- @Override
- public int compareTo(GroupByObject o) {
- //if we have several groupings, the comparison is performed on the group by order
- int result = this.groupByIndex.compareTo(o.groupByIndex);
-
- if (result == 0) {
- //if the datatypes are not the same here, comparison is not possible
- if (this.value == null || o.value == null || this.value.getClass().equals(o.value.getClass())) {
- result = DefaultComparator.getInstance().compare(value, o.value);
- }
- }
-
- return result;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + groupByIndex;
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- GroupByObject other = (GroupByObject) obj;
- if (groupByIndex != other.groupByIndex)
- return false;
- if (value == null) {
- if (other.value != null)
- return false;
- } else if (!value.equals(other.value))
- return false;
- return true;
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Original authors and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Original authors and others - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.nebula.widgets.nattable.config.DefaultComparator;
+
+/**
+ * This class is used to add tree items that are added to the tree path for grouping purposes. Contains the value that is used for grouping and the grouping index to ensure the correct ordering.
+ */
+public class GroupByObject implements Comparable<GroupByObject> {
+
+ /** The columnIndex->value */
+ private final List<Entry<Integer, Object>> descriptor;
+
+ /**
+ * The value that is used for grouping.
+ */
+ private final Object value;
+
+ /**
+ * @param value
+ * The value that is used for grouping.
+ * @param descriptor
+ * The description of the grouping (Index->Value)
+ */
+ public GroupByObject(Object value, List<Entry<Integer, Object>> descriptor) {
+ this.value = value;
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * @return The value that is used for grouping.
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * @return The description of the grouping (Index->Value)
+ */
+ public Collection<Entry<Integer, Object>> getDescriptor() {
+ return descriptor;
+ }
+
+ @Override
+ public String toString() {
+ // Without adjusting a lot of API and adding dependencies to the DataLayer and the ConfigRegistry
+ // we can not get the IDataConverter here. It might be solvable with the next generation because
+ // we can then inject the necessary values. Until then you should consider implementing toString()
+ return value.toString();
+ }
+
+ @Override
+ public int compareTo(GroupByObject o) {
+ if (this.value.getClass().equals(o.value.getClass())) {
+ return DefaultComparator.getInstance().compare(value, o.value);
+ }
+ return Integer.valueOf(this.descriptor.hashCode()).compareTo(o.descriptor.hashCode());
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((descriptor == null) ? 0 : descriptor.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ GroupByObject other = (GroupByObject) obj;
+ if (descriptor == null) {
+ if (other.descriptor != null)
+ return false;
+ } else if (!descriptor.equals(other.descriptor))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByTreeFormat.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByTreeFormat.java
index d4058d3..20d4393 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByTreeFormat.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/GroupByTreeFormat.java
@@ -1,136 +1,176 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2013 Original authors and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Original authors and others - initial API and implementation
- ******************************************************************************/
-package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
-
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.nebula.widgets.nattable.config.DefaultComparator;
-import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
-
-import ca.odell.glazedlists.TreeList;
-
-/**
- * The TreeList.Format that is used by the TreeList that is created and used by the
- * GroupByDataLayer. Note that the TreeList created by the GroupByDataLayer is generic for
- * Object because the groupBy functionality will add GroupByObjects to the path for creating
- * the grouping.
- *
- * @param <T> The type of the base objects carried in the TreeList.
- */
-public class GroupByTreeFormat<T> implements TreeList.Format<Object> {
-
- /**
- * The GroupByModel that carries the information about the groupBy states.
- */
- private final GroupByModel model;
- /**
- * The IColumnAccessor that is used to get the column value for the columns that are grouped by.
- * Needed for compare operations and creating the path in the tree.
- */
- private final IColumnAccessor<T> columnAccessor;
- /**
- * Comparator that is used to sort the TreeList based on the groupBy information.
- */
- private final GroupByComparator groupByComparator = new GroupByComparator();
-
- /**
- *
- * @param model The GroupByModel that carries the information about the groupBy states.
- * @param columnAccessor The IColumnAccessor that is used to get the column value
- * for the columns that are grouped by. Needed for compare operations and
- * creating the path in the tree.
- */
- public GroupByTreeFormat(GroupByModel model, IColumnAccessor<T> columnAccessor) {
- this.model = model;
- this.columnAccessor = columnAccessor;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void getPath(List<Object> path, Object element) {
- int groupByIndex = 0;
- for (int columnIndex : model.getGroupByColumnIndexes()) {
- //add a GroupByObject that contains the value contained in the column which is grouped
- Object columnValue = columnAccessor.getDataValue((T) element, columnIndex);
- path.add(new GroupByObject(groupByIndex++, columnValue));
- }
-
- path.add(element);
- }
-
- @Override
- public boolean allowsChildren(Object element) {
- return true;
- }
-
- @Override
- public Comparator<Object> getComparator(int depth) {
- //if there is no grouping we do not provide a comparator for the tree
- if (this.model.getGroupByColumnIndexes().isEmpty()) {
- return null;
- }
-
- return this.groupByComparator;
- }
-
- /**
- * Comparator that is used to sort the TreeList based on the groupBy information.
- *
- * @author Dirk Fauth
- *
- */
- class GroupByComparator implements Comparator<Object> {
-
- @SuppressWarnings("unchecked")
- @Override
- public int compare(Object o1, Object o2) {
- for (int columnIndex : model.getGroupByColumnIndexes()) {
- if (o1 == null) {
- if (o2 == null) {
- return 0;
- } else {
- return -1;
- }
- } else if (o2 == null) {
- return 1;
- }
- else {
- Object columnValue1 = null;
- Object columnValue2 = null;
- int result = 0;
- if (o1 instanceof GroupByObject && o2 instanceof GroupByObject) {
- columnValue1 = o1;
- columnValue2 = o2;
- result = ((GroupByObject)o1).compareTo((GroupByObject)o2);
- }
- else if (o1 instanceof GroupByObject && !(o2 instanceof GroupByObject)) {
- result = 1;
- }
- else if (!(o1 instanceof GroupByObject) && o2 instanceof GroupByObject) {
- result = -1;
- }
- else {
- columnValue1 = columnAccessor.getDataValue((T)o1, columnIndex);
- columnValue2 = columnAccessor.getDataValue((T)o2, columnIndex);
- result = DefaultComparator.getInstance().compare(columnValue1, columnValue2);
- }
-
- if (result != 0) {
- return result;
- }
- }
- }
- return 0;
- }
-
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 Original authors and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Original authors and others - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.nebula.widgets.nattable.config.DefaultComparator;
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+import org.eclipse.nebula.widgets.nattable.sort.ISortModel;
+
+import ca.odell.glazedlists.TreeList;
+
+/**
+ * The TreeList.Format that is used by the TreeList that is created and used by the
+ * GroupByDataLayer. Note that the TreeList created by the GroupByDataLayer is generic for
+ * Object because the groupBy functionality will add GroupByObjects to the path for creating
+ * the grouping.
+ *
+ * @param <T> The type of the base objects carried in the TreeList.
+ */
+public class GroupByTreeFormat<T> implements TreeList.Format<Object> {
+
+ /**
+ * The GroupByModel that carries the information about the groupBy states.
+ */
+ private final GroupByModel model;
+ /**
+ * The IColumnAccessor that is used to get the column value for the columns that are grouped by.
+ * Needed for compare operations and creating the path in the tree.
+ */
+ private final IColumnAccessor<T> columnAccessor;
+ /**
+ * Comparator that is used to sort the TreeList based on the groupBy information.
+ */
+ private final GroupByComparator groupByComparator = new GroupByComparator();
+ /**
+ * To provide sorting functionality
+ */
+ private ISortModel sortModel;
+
+ /**
+ *
+ * @param model The GroupByModel that carries the information about the groupBy states.
+ * @param columnAccessor The IColumnAccessor that is used to get the column value
+ * for the columns that are grouped by. Needed for compare operations and
+ * creating the path in the tree.
+ */
+ public GroupByTreeFormat(GroupByModel model, IColumnAccessor<T> columnAccessor) {
+ this.model = model;
+ this.columnAccessor = columnAccessor;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void getPath(List<Object> path, Object element) {
+ List<Integer> groupByColunns = model.getGroupByColumnIndexes();
+ if (!groupByColunns.isEmpty()) {
+ List<Entry<Integer, Object>> descriptor = new ArrayList<Entry<Integer, Object>>();
+ for (int columnIndex : groupByColunns) {
+ // Build a unique descriptor for the group
+ Object columnValue = columnAccessor.getDataValue((T) element, columnIndex);
+ descriptor.add(new AbstractMap.SimpleEntry<Integer, Object>(columnIndex, columnValue));
+ GroupByObject groupByObject = new GroupByObject(columnValue, new ArrayList<Entry<Integer, Object>>(descriptor));
+ path.add(groupByObject);
+ }
+ }
+ path.add(element);
+ }
+
+ @Override
+ public boolean allowsChildren(Object element) {
+ return true;
+ }
+
+ @Override
+ public Comparator<Object> getComparator(int depth) {
+ //if there is no grouping we do not provide a comparator for the tree
+ if (this.model.getGroupByColumnIndexes().isEmpty()) {
+ return null;
+ }
+
+ return this.groupByComparator;
+ }
+
+ public void setSortModel(ISortModel model) {
+ sortModel = model;
+ }
+
+ /**
+ * Comparator that is used to sort the TreeList based on the groupBy information.
+ *
+ * @author Dirk Fauth
+ *
+ */
+ class GroupByComparator implements Comparator<Object> {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public int compare(Object o1, Object o2) {
+ for (int columnIndex : model.getGroupByColumnIndexes()) {
+ if (o1 == null) {
+ if (o2 == null) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else if (o2 == null) {
+ return 1;
+ } else {
+ Object columnValue1 = null;
+ Object columnValue2 = null;
+ int result = 0;
+ if (o1 instanceof GroupByObject && o2 instanceof GroupByObject) {
+ columnValue1 = o1;
+ columnValue2 = o2;
+ result = ((GroupByObject) o1).compareTo((GroupByObject) o2);
+
+ if (result != 0) {
+ if (sortModel != null) {
+ // Compare aggregated columns
+ for (int sortedColumnIndex : sortModel.getSortedColumnIndexes()) {
+ if (o1 instanceof GroupByObject && o2 instanceof GroupByObject) {
+ GroupByObject grp1 = (GroupByObject) o1;
+ GroupByObject grp2 = (GroupByObject) o2;
+ columnValue1 = columnAccessor.getDataValue((T) grp1, sortedColumnIndex);
+ columnValue2 = columnAccessor.getDataValue((T) grp2, sortedColumnIndex);
+ if (columnValue1 != null && columnValue2 != null) {
+ int res = DefaultComparator.getInstance().compare(columnValue1,
+ columnValue2);
+ if (res == 0) {
+ continue;
+ }
+ switch (sortModel.getSortDirection(sortedColumnIndex)) {
+ case ASC:
+ result = res;
+ break;
+ case DESC:
+ result = res * -1;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (o1 instanceof GroupByObject && !(o2 instanceof GroupByObject)) {
+ result = 1;
+ } else if (!(o1 instanceof GroupByObject) && o2 instanceof GroupByObject) {
+ result = -1;
+ } else {
+ columnValue1 = columnAccessor.getDataValue((T) o1, columnIndex);
+ columnValue2 = columnAccessor.getDataValue((T) o2, columnIndex);
+ result = DefaultComparator.getInstance().compare(columnValue1, columnValue2);
+ }
+
+ if (result != 0) {
+ return result;
+ }
+ }
+ }
+ return 0;
+ }
+
+ }
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryColumnAccessor.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryColumnAccessor.java
new file mode 100644
index 0000000..3d6b21b
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryColumnAccessor.java
@@ -0,0 +1,57 @@
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByColumnAccessor;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByDataLayer;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.GroupByObject;
+import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
+
+public class GroupBySummaryColumnAccessor<T> extends GroupByColumnAccessor<Object> {
+
+ private Map<Integer, IGroupBySummaryProvider<T>> summaryProviderByColumn;
+ private final GroupByDataLayer<T> groupByDataLayer;
+ private final IConfigRegistry configRegistry;
+
+ private Map<Integer, IGroupBySummaryProvider<T>> getSummaryProviderByColumn() {
+ if (summaryProviderByColumn == null) {
+ summaryProviderByColumn = new HashMap<Integer, IGroupBySummaryProvider<T>>();
+ for (int columnIndex = 0; columnIndex < groupByDataLayer.getColumnCount(); columnIndex++) {
+ int columnPosition = groupByDataLayer.getColumnPositionByIndex(columnIndex);
+ List<String> labels = groupByDataLayer.getConfigLabelsByPosition(columnPosition, 0).getLabels();
+ @SuppressWarnings("unchecked")
+ IGroupBySummaryProvider<T> summaryProvider = configRegistry.getConfigAttribute(
+ GroupBySummaryConfigAttributes.GROUP_BY_SUMMARY_PROVIDER, DisplayMode.NORMAL, labels);
+ if (summaryProvider != null) {
+ summaryProviderByColumn.put(columnIndex, summaryProvider);
+ }
+ }
+ }
+ return summaryProviderByColumn;
+ }
+
+ public GroupBySummaryColumnAccessor(IColumnAccessor<Object> columnAccessor,
+ IConfigRegistry configRegistry, GroupByDataLayer<T> groupByDataLayer) {
+ super(columnAccessor);
+ this.groupByDataLayer = groupByDataLayer;
+ this.configRegistry = configRegistry;
+ }
+
+ public Object getDataValue(Object rowObject, int columnIndex) {
+ if (rowObject instanceof GroupByObject) {
+ IGroupBySummaryProvider<T> summaryProvider = getSummaryProviderByColumn().get(columnIndex);
+ if (summaryProvider == null) {
+ return super.getDataValue(rowObject, columnIndex);
+ }
+ GroupByObject groupByObject = (GroupByObject) rowObject;
+ List<T> children = groupByDataLayer.getElementsInGroup(groupByObject);
+ return summaryProvider.summarize(columnIndex, children);
+ } else {
+ return columnAccessor.getDataValue(rowObject, columnIndex);
+ }
+ }
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryConfigAttributes.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryConfigAttributes.java
new file mode 100644
index 0000000..f7294e1
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/GroupBySummaryConfigAttributes.java
@@ -0,0 +1,11 @@
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary;
+
+import org.eclipse.nebula.widgets.nattable.style.ConfigAttribute;
+
+public class GroupBySummaryConfigAttributes {
+
+ /**
+ * The configuration attribute that is used to calculate the summary for a column.
+ */
+ public static final ConfigAttribute<IGroupBySummaryProvider> GROUP_BY_SUMMARY_PROVIDER = new ConfigAttribute<IGroupBySummaryProvider>();
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/IGroupBySummaryProvider.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/IGroupBySummaryProvider.java
new file mode 100644
index 0000000..ab32942
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/IGroupBySummaryProvider.java
@@ -0,0 +1,14 @@
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary;
+
+import java.util.List;
+
+public interface IGroupBySummaryProvider<T> {
+
+ public static final Object DEFAULT_SUMMARY_VALUE = "..."; //$NON-NLS-1$
+
+ /**
+ * @param columnIndex The column index of the column for which the summary should be calculated.
+ * @return The calculated summary value for the column.
+ */
+ public Object summarize(int columnIndex, List<T> children);
+} \ No newline at end of file
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/SummationGroupBySummaryProvider.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/SummationGroupBySummaryProvider.java
new file mode 100644
index 0000000..f22baeb
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/groupBy/summary/SummationGroupBySummaryProvider.java
@@ -0,0 +1,27 @@
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.groupBy.summary;
+
+import java.util.List;
+
+import org.eclipse.nebula.widgets.nattable.data.IColumnAccessor;
+
+public class SummationGroupBySummaryProvider<T> implements IGroupBySummaryProvider<T> {
+
+ private final IColumnAccessor<T> columnAccessor;
+
+ public SummationGroupBySummaryProvider(IColumnAccessor<T> columnAccessor) {
+ this.columnAccessor = columnAccessor;
+ }
+
+ @Override
+ public Object summarize(int columnIndex, List<T> children) {
+ float summaryValue = 0;
+ for (T child : children) {
+ Object dataValue = columnAccessor.getDataValue(child, columnIndex);
+ if (dataValue instanceof Number) {
+ summaryValue = summaryValue + Float.parseFloat(dataValue.toString());
+ }
+ }
+ return summaryValue;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/tree/GlazedListTreeData.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/tree/GlazedListTreeData.java
index 697cbb5..1fd1cae 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/tree/GlazedListTreeData.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/tree/GlazedListTreeData.java
@@ -11,6 +11,7 @@
package org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.eclipse.nebula.widgets.nattable.tree.ITreeData;
@@ -21,18 +22,19 @@ import ca.odell.glazedlists.TreeList.Node;
/**
* Implementation of ITreeData that operates on a GlazedLists TreeList.
*
- * @param <T> The type of objects that are contained in the TreeList.
+ * @param <T>
+ * The type of objects that are contained in the TreeList.
*/
public class GlazedListTreeData<T> implements ITreeData<T> {
private final TreeList<T> treeList;
-
+
public GlazedListTreeData(TreeList<T> treeList) {
this.treeList = treeList;
}
-
+
@Override
- public String formatDataForDepth(int depth, int index){
+ public String formatDataForDepth(int depth, int index) {
return formatDataForDepth(depth, getDataAtIndex(index));
}
@@ -44,7 +46,7 @@ public class GlazedListTreeData<T> implements ITreeData<T> {
return ""; //$NON-NLS-1$
}
}
-
+
@Override
public T getDataAtIndex(int index) {
return this.treeList.get(index);
@@ -59,7 +61,7 @@ public class GlazedListTreeData<T> implements ITreeData<T> {
public int getDepthOfData(int index) {
return this.treeList.depth(index);
}
-
+
@Override
public int indexOf(T object) {
return this.treeList.indexOf(object);
@@ -69,7 +71,7 @@ public class GlazedListTreeData<T> implements ITreeData<T> {
public boolean hasChildren(T object) {
return hasChildren(indexOf(object));
}
-
+
@Override
public boolean hasChildren(int index) {
return this.treeList.hasChildren(index);
@@ -80,49 +82,71 @@ public class GlazedListTreeData<T> implements ITreeData<T> {
return getChildren(indexOf(object));
}
+ private List<T> getNodeChildren(Node<T> treeNode) {
+ List<T> children = new ArrayList<T>();
+ for (Node<T> child : treeNode.getChildren()) {
+ children.add(child.getElement());
+ children.addAll(getNodeChildren(child));
+ }
+ return children;
+ }
+
+ @Override
+ public List<T> getChildren(T object, boolean fullDepth) {
+ if (fullDepth == false) {
+ return getChildren(object);
+ }
+ int index = indexOf(object);
+ if (index >= 0) {
+ Node<T> treeNode = this.treeList.getTreeNode(index);
+ return getNodeChildren(treeNode);
+ }
+ return Collections.emptyList();
+ }
+
@Override
public List<T> getChildren(int index) {
- List <T> children = new ArrayList<T>();
+ List<T> children = new ArrayList<T>();
if (index >= 0) {
Node<T> treeNode = this.treeList.getTreeNode(index);
if (treeNode != null) {
List<Node<T>> childrenNodes = treeNode.getChildren();
- for(Node<T> node : childrenNodes){
+ for (Node<T> node : childrenNodes) {
children.add(node.getElement());
}
}
}
return children;
}
-
+
public void collapse(T object) {
collapse(indexOf(object));
};
-
+
public void expand(T object) {
expand(indexOf(object));
};
-
+
public void collapse(int index) {
toggleExpanded(index, false);
};
-
+
public void expand(int index) {
toggleExpanded(index, true);
};
-
- private void toggleExpanded(int index, boolean expanded){
+
+ private void toggleExpanded(int index, boolean expanded) {
this.treeList.setExpanded(index, expanded);
}
-
- public boolean isExpanded(T object){
+
+ public boolean isExpanded(T object) {
return isExpanded(indexOf(object));
}
-
- public boolean isExpanded(int index){
+
+ public boolean isExpanded(int index) {
return this.treeList.isExpanded(index);
}
-
+
@Override
public List<T> getRoots() {
List<T> roots = new ArrayList<T>();