import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.DefaultComparator;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfiguration;
import org.eclipse.nebula.widgets.nattable.config.NullComparator;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.DetailGlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsDataProvider;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.DefaultGlazedListsFilterStrategy;
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.filterrow.FilterIconPainter;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowPainter;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
import org.eclipse.nebula.widgets.nattable.hideshow.RowHideShowLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
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.selection.config.RowOnlySelectionBindings;
import org.eclipse.nebula.widgets.nattable.selection.config.RowOnlySelectionConfiguration;
import org.eclipse.nebula.widgets.nattable.sort.ISortModel;
import org.eclipse.nebula.widgets.nattable.sort.SortConfigAttributes;
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.style.theme.ThemeConfiguration;
import org.eclipse.nebula.widgets.nattable.test.fixture.data.RowDataListFixture;
import org.eclipse.nebula.widgets.nattable.tree.ITreeData;
import org.eclipse.nebula.widgets.nattable.tree.SortableTreeComparator;
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
import org.eclipse.nebula.widgets.nattable.tree.config.DefaultTreeLayerConfiguration;
import org.eclipse.nebula.widgets.nattable.ui.menu.HeaderMenuConfiguration;
import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TreeList;
public class TreeGridExample extends AbstractNatExample {
protected static final String NO_SORT_LABEL = "noSortLabel";
public static void main(String[] args) {
StandaloneNatExampleRunner.run(800, 400, new TreeGridExample());
}
@Override
public Control createExampleControl(Composite parent) {
ConfigRegistry configRegistry = new ConfigRegistry();
configRegistry.registerConfigAttribute(
SortConfigAttributes.SORT_COMPARATOR, DefaultComparator.getInstance());
// Underlying data source
createDatums();
EventList eventList = GlazedLists.eventList(this.datums.values());
SortedList sortedList = new SortedList(eventList, null);
FilterList<Datum> filterList = new FilterList<Datum>(sortedList);
String[] propertyNames = new String[] { "foo", "bar" };
IColumnPropertyAccessor columnPropertyAccessor = new ReflectiveColumnPropertyAccessor(
propertyNames);
// Column header layer
IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(
propertyNames);
DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(
columnHeaderDataProvider);
ISortModel sortModel = new GlazedListsSortModel(sortedList,
columnPropertyAccessor, configRegistry, columnHeaderDataLayer);
final TreeList treeList = new TreeList(filterList,
new DatumTreeFormat(sortModel), new DatumExpansionModel());
GlazedListTreeData treeData = new GlazedListTreeData(treeList);
GlazedListsDataProvider bodyDataProvider = new GlazedListsDataProvider(
treeList, columnPropertyAccessor);
DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
// GlazedListsEventLayer glazedListsEventLayer =
// new GlazedListsEventLayer(bodyDataLayer, treeList);
DetailGlazedListsEventLayer glazedListsEventLayer = new DetailGlazedListsEventLayer(
bodyDataLayer, treeList);
// Body layer
ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(
glazedListsEventLayer);
ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(
columnReorderLayer);
RowHideShowLayer rowHideShowLayer = new RowHideShowLayer(
columnHideShowLayer);
// Switch the ITreeRowModel implementation between using native grid
// Hide/Show or GlazedList TreeList Hide/Show
// TreeLayer treeLayer = new TreeLayer(rowHideShowLayer, new
// TreeRowModel(treeData), true);
TreeLayer treeLayer = new TreeLayer(rowHideShowLayer,
new GlazedListTreeRowModel(treeData), false);
SelectionLayer selectionLayer = new SelectionLayer(treeLayer);
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
columnHeaderDataLayer, viewportLayer, selectionLayer);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
// ColumnOverrideLabelAccumulator labelAccumulator = new ColumnOverrideLabelAccumulator(
// columnHeaderDataLayer);
// columnHeaderDataLayer.setConfigLabelAccumulator(labelAccumulator);
// Register labels
SortHeaderLayer sortHeaderLayer = new SortHeaderLayer(
columnHeaderLayer, sortModel, false);
final FilterRowHeaderComposite filterRowHeaderLayer =
new FilterRowHeaderComposite(
new DefaultGlazedListsFilterStrategy(
filterList,
columnPropertyAccessor,
configRegistry),
sortHeaderLayer,
columnHeaderDataLayer.getDataProvider(),
configRegistry);
// Row header layer
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(
rowHeaderDataProvider);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
viewportLayer, selectionLayer);
// Corner layer
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
columnHeaderDataProvider, rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer,
rowHeaderLayer, filterRowHeaderLayer);
// Grid
GridLayer gridLayer = new GridLayer(viewportLayer, filterRowHeaderLayer,
rowHeaderLayer, cornerLayer);
NatTable natTable = new NatTable(parent, gridLayer, false);
natTable.addConfiguration(new AbstractRegistryConfiguration() {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
// Shade the row to be slightly darker than the blue background.
final Style rowStyle = new Style();
rowStyle.setAttributeValue(
CellStyleAttributes.BACKGROUND_COLOR,
GUIHelper.getColor(197, 212, 231));
configRegistry.registerConfigAttribute(
CellConfigAttributes.CELL_STYLE, rowStyle,
DisplayMode.NORMAL, GridRegion.FILTER_ROW);
configRegistry.registerConfigAttribute(
CellConfigAttributes.CELL_PAINTER,
new FilterRowPainter(new FilterIconPainter(GUIHelper
.getImage("filter"))), DisplayMode.NORMAL, GridRegion.FILTER_ROW);
}
});
natTable.setConfigRegistry(configRegistry);
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
natTable.addConfiguration(new HeaderMenuConfiguration(natTable) {
@Override
protected PopupMenuBuilder createRowHeaderMenu(NatTable natTable) {
return super.createRowHeaderMenu(natTable)
.withHideRowMenuItem().withShowAllRowsMenuItem();
}
});
natTable.addConfiguration(new DefaultTreeLayerConfiguration(treeLayer));
natTable.addConfiguration(new SingleClickSortConfiguration());
natTable.addConfiguration(getCustomComparatorConfiguration(columnHeaderLayer));
// Uncomment to see the native tree list printed to stout.
// printTree(treeList, treeData);
natTable.configure();
return natTable;
}
private static class DatumTreeFormat implements TreeList.Format<Datum> {
private final ISortModel sortModel;
public DatumTreeFormat(ISortModel sortModel) {
this.sortModel = sortModel;
}
@Override
public void getPath(List path, Datum element) {
path.add(element);
Datum parent = element.getParent();
while (parent != null) {
path.add(parent);
parent = parent.getParent();
}
Collections.reverse(path);
}
@Override
public boolean allowsChildren(Datum element) {
return true;
}
@Override
public Comparator getComparator(int depth) {
return new SortableTreeComparator(
GlazedLists.beanPropertyComparator(Datum.class, "foo"),
this.sortModel);
}
}
private static class DatumExpansionModel implements
TreeList.ExpansionModel<Datum> {
@Override
public boolean isExpanded(Datum element, List path) {
return true;
}
@Override
public void setExpanded(Datum element, List path,
boolean expanded) {}
}
protected void printTree(TreeList<Datum> treeList, ITreeData treeData) {
System.out.println(treeList.size());
for (int i = 0; i < treeList.size(); i++) {
final Datum location = treeList.get(i);
final int depth = treeList.depth(i);
final boolean hasChildren = treeList.hasChildren(i);
final boolean isExpanded = treeList.isExpanded(i);
for (int j = 0; j < depth; j++)
System.out.print("\t");
if (hasChildren)
System.out.print(isExpanded ? "- " : "+ ");
else
System.out.print(" ");
System.out.println(location.getFoo());
}
}
public class Datum {
/**
*
*/
private final Datum parent;
private String foo;
private int bar;
public Datum(Datum parent, String foo, int bar) {
this.parent = parent;
this.foo = foo;
this.bar = bar;
}
public Datum getParent() {
return this.parent;
}
public String getFoo() {
return this.foo;
}
public int getBar() {
return this.bar;
}
@Override
public String toString() {
return "[" + "parent=" + this.parent + ", foo=" + this.foo + ", bar=" + this.bar
+ "]";
}
}
private Map datums = new HashMap();
private void createDatum(String parent, String foo, int bar) {
Datum datum = new Datum((Datum) this.datums.get(parent), foo, bar);
this.datums.put(foo, datum);
}
private void createDatums() {
createDatum(null, "root", 1);
createDatum("root", "A", 10);
createDatum("A", "A.1", 100);
createDatum("A", "A.2", 110);
createDatum("A", "A.3", 120);
createDatum("root", "B", 20);
createDatum("B", "B.1", 200);
createDatum("B", "B.2", 210);
createDatum("root", "C", 30);
createDatum("C", "C.1", 330);
createDatum("C", "C.2", 370);
createDatum("C", "C.3", 322);
createDatum("C", "C.4", 310);
createDatum("C", "C.5", 315);
createDatum(null, "root2", 2);
createDatum("root2", "X", 70);
createDatum("X", "X.1", 700);
createDatum("X", "X.2", 710);
createDatum("X", "X.3", 720);
createDatum("root2", "Y", 80);
createDatum("Y", "Y.1", 800);
createDatum("Y", "Y.2", 810);
createDatum("root2", "Z", 90);
createDatum("Z", "Z.1", 900);
createDatum("Z", "Z.2", 910);
createDatum("Z", "Z.3", 920);
createDatum("Z", "Z.4", 930);
createDatum("Z", "Z.5", 940);
}
private IConfiguration getCustomComparatorConfiguration(
final AbstractLayer columnHeaderDataLayer) {
return new AbstractRegistryConfiguration() {
@Override
public void configureRegistry(IConfigRegistry configRegistry) {
// Add label accumulator
ColumnOverrideLabelAccumulator labelAccumulator = new ColumnOverrideLabelAccumulator(
columnHeaderDataLayer);
columnHeaderDataLayer
.setConfigLabelAccumulator(labelAccumulator);
labelAccumulator
.registerColumnOverrides(0,
// RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.ASK_PRICE_PROP_NAME),
NO_SORT_LABEL);
// Register null comparator to disable sort
configRegistry
.registerConfigAttribute(
SortConfigAttributes.SORT_COMPARATOR,
DefaultComparator.getInstance(), DisplayMode.NORMAL,
NO_SORT_LABEL);
}
};
}
}
]]>