finished event handling in RowHideShowLayer and created GlazedListsRowHideShowLayer
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
index 0054dfa..04191ed 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/RowHideShowLayer.java
@@ -56,68 +56,77 @@
public void handleLayerEvent(ILayerEvent event) {
if (event instanceof IStructuralChangeEvent) {
IStructuralChangeEvent structuralChangeEvent = (IStructuralChangeEvent) event;
- if (structuralChangeEvent.isVerticalStructureChanged() && structuralChangeEvent.convertToLocal(this)) {
+ if (structuralChangeEvent.isVerticalStructureChanged()) {
Collection<StructuralDiff> rowDiffs = structuralChangeEvent.getRowDiffs();
- if (rowDiffs != null) {
- List<Integer> toRemove = new ArrayList<Integer>();
- for (Iterator<StructuralDiff> diffIterator = rowDiffs.iterator(); diffIterator.hasNext();) {
- StructuralDiff rowDiff = diffIterator.next();
- if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.DELETE)) {
- Range beforePositionRange = rowDiff.getBeforePositionRange();
- for (Iterator<Integer> it = this.hiddenRowIndexes.iterator(); it.hasNext();) {
- Integer hiddenRow = it.next();
- if (hiddenRow == beforePositionRange.start) {
- toRemove.add(hiddenRow);
- diffIterator.remove();
- //FIXME modify other row indexes
- }
- }
- }
- }
-
- handleVerticalStructureUpdates(rowDiffs);
+ if (rowDiffs != null && !rowDiffs.isEmpty()) {
+ handleRowDelete(rowDiffs);
+ handleRowInsert(rowDiffs);
}
}
}
super.handleLayerEvent(event);
}
-
- protected void handleVerticalStructureUpdates(Collection<StructuralDiff> rowDiffs) {
- for (StructuralDiff rowDiff : rowDiffs) {
+ /**
+ * Will check for events that indicate that a rows has been deleted. In that case the stored
+ * hidden indexes need to be updated because the index of the rows might have changed.
+ * E.g. Row with index 3 is hidden in this layer, deleting row at index 1 will cause the row at index
+ * 3 to be moved at index 2. Without transforming the index regarding the delete event, the wrong
+ * row would be hidden.
+ * @param rowDiffs The collection of {@link StructuralDiff}s to handle
+ */
+ protected void handleRowDelete(Collection<StructuralDiff> rowDiffs) {
+ List<Integer> toRemove = new ArrayList<Integer>();
+ for (Iterator<StructuralDiff> diffIterator = rowDiffs.iterator(); diffIterator.hasNext();) {
+ StructuralDiff rowDiff = diffIterator.next();
if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.DELETE)) {
Range beforePositionRange = rowDiff.getBeforePositionRange();
- Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
- for (Integer hiddenRow : this.hiddenRowIndexes) {
- if (hiddenRow != beforePositionRange.start) {
- //the deleted row was not hidden before
- //if it was hidden it will not be added to the new collection
- if (hiddenRow > beforePositionRange.start) {
- //if the hidden row was before the deleted row
- //we need to lower the index because of missing a row
- modifiedHiddenRows.add(hiddenRow-1);
- }
- else {
- modifiedHiddenRows.add(hiddenRow);
- }
- }
- }
- RowHideShowLayer.this.hiddenRowIndexes.clear();
- RowHideShowLayer.this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+ toRemove.add(underlyingLayer.getRowIndexByPosition(beforePositionRange.start));
}
- else if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.ADD)) {
+ }
+ //remove the hidden row indexes that are deleted
+ this.hiddenRowIndexes.removeAll(toRemove);
+
+ //modify hidden row indexes regarding the deleted rows
+ Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
+ for (Integer hiddenRow : this.hiddenRowIndexes) {
+ //check number of removed indexes that are lower than the current one
+ int deletedBefore = 0;
+ for (Integer removed : toRemove) {
+ if (removed < hiddenRow) {
+ deletedBefore++;
+ }
+ }
+ modifiedHiddenRows.add(hiddenRow-deletedBefore);
+ }
+ this.hiddenRowIndexes.clear();
+ this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+ }
+
+ /**
+ * Will check for events that indicate that a rows are added. In that case the stored
+ * hidden indexes need to be updated because the index of the rows might have changed.
+ * E.g. Row with index 3 is hidden in this layer, adding a row at index 1 will cause the row at index
+ * 3 to be moved to index 4. Without transforming the index regarding the add event, the wrong
+ * row would be hidden.
+ * @param rowDiffs The collection of {@link StructuralDiff}s to handle
+ */
+ protected void handleRowInsert(Collection<StructuralDiff> rowDiffs) {
+ for (StructuralDiff rowDiff : rowDiffs) {
+ if (rowDiff.getDiffType() != null && rowDiff.getDiffType().equals(DiffTypeEnum.ADD)) {
Range beforePositionRange = rowDiff.getBeforePositionRange();
Set<Integer> modifiedHiddenRows = new HashSet<Integer>();
+ int beforeIndex = underlyingLayer.getRowIndexByPosition(beforePositionRange.start);
for (Integer hiddenRow : this.hiddenRowIndexes) {
- if (hiddenRow >= beforePositionRange.start) {
+ if (hiddenRow >= beforeIndex) {
modifiedHiddenRows.add(hiddenRow+1);
}
else {
modifiedHiddenRows.add(hiddenRow);
}
}
- RowHideShowLayer.this.hiddenRowIndexes.clear();
- RowHideShowLayer.this.hiddenRowIndexes.addAll(modifiedHiddenRows);
+ this.hiddenRowIndexes.clear();
+ this.hiddenRowIndexes.addAll(modifiedHiddenRows);
}
}
}
@@ -175,24 +184,11 @@
fireLayerEvent(new HideRowPositionsEvent(this, rowPositions));
}
- public void showRowIndexes(int[] rowIndexes) {
- Set<Integer> rowIndexesSet = new HashSet<Integer>();
- for (int i = 0; i < rowIndexes.length; i++) {
- rowIndexesSet.add(Integer.valueOf(rowIndexes[i]));
- }
- hiddenRowIndexes.removeAll(rowIndexesSet);
+ public void showRowIndexes(Collection<Integer> rowIndexes) {
+ hiddenRowIndexes.removeAll(rowIndexes);
invalidateCache();
fireLayerEvent(new ShowRowPositionsEvent(this, getRowPositionsByIndexes(rowIndexes)));
}
-
- protected void showRowIndexes(Collection<Integer> rowIndexes) {
- for (int rowIndex : rowIndexes) {
- hiddenRowIndexes.remove(Integer.valueOf(rowIndex));
- }
- invalidateCache();
- // Since we are exposing this method for showing individual rows, a structure event must be fired here.
- fireLayerEvent(new ShowRowPositionsEvent(this, rowIndexes));
- }
public void showAllRows() {
Collection<Integer> hiddenRows = new ArrayList<Integer>(hiddenRowIndexes);
@@ -201,7 +197,7 @@
fireLayerEvent(new ShowRowPositionsEvent(this, hiddenRows));
}
- private Collection<Integer> getRowPositionsByIndexes(int[] rowIndexes) {
+ private Collection<Integer> getRowPositionsByIndexes(Collection<Integer> rowIndexes) {
Collection<Integer> rowPositions = new HashSet<Integer>();
for (int rowIndex : rowIndexes) {
rowPositions.add(Integer.valueOf(getRowPositionByIndex(rowIndex)));
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
index 8dbbe85..6c9e176 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommand.java
@@ -10,23 +10,39 @@
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.hideshow.command;
+import java.util.ArrayList;
+import java.util.Collection;
+
import org.eclipse.nebula.widgets.nattable.command.AbstractContextFreeCommand;
+/**
+ * Command for showing hidden rows again.
+ */
public class MultiRowShowCommand extends AbstractContextFreeCommand {
- private final int[] rowIndexes;
+ /**
+ * The indexes of the rows that should be showed again.
+ */
+ private final Collection<Integer> rowIndexes;
- public MultiRowShowCommand(int[] rowIndexes) {
+ /**
+ *
+ * @param rowIndexes The indexes of the rows that should be showed again.
+ */
+ public MultiRowShowCommand(Collection<Integer> rowIndexes) {
this.rowIndexes = rowIndexes;
}
- protected MultiRowShowCommand(MultiRowShowCommand command) {
- rowIndexes = new int[command.rowIndexes.length];
- System.arraycopy(command.rowIndexes, 0, rowIndexes, 0, command.rowIndexes.length);
- }
-
- public int[] getRowIndexes() {
+ /**
+ *
+ * @return The indexes of the rows that should be showed again.
+ */
+ public Collection<Integer> getRowIndexes() {
return rowIndexes;
}
+ @Override
+ public MultiRowShowCommand cloneCommand() {
+ return new MultiRowShowCommand(new ArrayList<Integer>(this.rowIndexes));
+ }
}
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
index 5a0563e..911cb4d 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/hideshow/command/MultiRowShowCommandHandler.java
@@ -27,8 +27,7 @@
@Override
protected boolean doCommand(MultiRowShowCommand command) {
- int[] columnIndexes = command.getRowIndexes();
- rowHideShowLayer.showRowIndexes(columnIndexes);
+ rowHideShowLayer.showRowIndexes(command.getRowIndexes());
return true;
}
diff --git a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
index f110629..9b376f3 100644
--- a/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.core/src/org/eclipse/nebula/widgets/nattable/tree/TreeLayer.java
@@ -12,7 +12,6 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -134,10 +133,6 @@
* @param parentIndex The index of the row that shows the node that should be collapsed
*/
public void collapseTreeRow(int parentIndex) {
- //TODO remember the hidden rows before collapse because they will be deleted
- //when using GlazedLists for collapse and therefore need to be restored on expand
-// storeHiddenRowStates(this.treeRowModel.getChildIndexes(parentIndex));
-
List<Integer> rowIndexes = this.treeRowModel.collapse(parentIndex);
List<Integer> rowPositions = new ArrayList<Integer>();
for (Integer rowIndex : rowIndexes) {
@@ -160,10 +155,6 @@
List<Integer> rowIndexes = this.treeRowModel.expand(parentIndex);
this.hiddenRowIndexes.removeAll(rowIndexes);
invalidateCache();
-
- //TODO restore the hidden states
-// restoreHiddenRowStates();
-
fireLayerEvent(new ShowRowPositionsEvent(this, rowIndexes));
}
@@ -178,34 +169,6 @@
return (underlyingLayer.getRowPositionByIndex(rowIndex) == -1);
}
- private List<Integer> hiddenCollapsed = new ArrayList<Integer>();
-
- private void storeHiddenRowStates(List<Integer> collapsed) {
- for (Integer rowIndex : collapsed) {
- if (isHiddenInUnderlyingLayer(rowIndex)) {
- hiddenCollapsed.add(rowIndex);
- }
- }
- }
-
- private void restoreHiddenRowStates() {
- List<Integer> hidePositions = new ArrayList<Integer>();
- for (Iterator<Integer> iterator = hiddenCollapsed.iterator(); iterator.hasNext();) {
- Integer rowIndex = iterator.next();
- if (!isHiddenInUnderlyingLayer(rowIndex)) {
- hidePositions.add(getRowPositionByIndex(rowIndex));
- iterator.remove();
- }
- }
- if (!hidePositions.isEmpty()) {
- int[] positions = new int[hidePositions.size()];
- for (int i = 0; i < hidePositions.size(); i++) {
- positions[i] = hidePositions.get(i);
- }
- new MultiRowHideCommand(this, positions);
- }
- }
-
@Override
public boolean doCommand(ILayerCommand command) {
//special command transformations are needed to hide also child nodes
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java
new file mode 100644
index 0000000..979ff09
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_500_Layers/_532_GlazedListsRowHideShowExample.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.examples._500_Layers;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
+import org.eclipse.nebula.widgets.nattable.examples.AbstractNatExample;
+import org.eclipse.nebula.widgets.nattable.examples.data.person.Person;
+import org.eclipse.nebula.widgets.nattable.examples.data.person.PersonService;
+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.hideshow.GlazedListsRowHideShowLayer;
+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.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.nebula.widgets.nattable.ui.menu.AbstractHeaderMenuConfiguration;
+import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
+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;
+
+/**
+ * Simple example showing how to add the row hide/show functionality to a grid that is build
+ * using GlazedLists and how to add the corresponding actions to the row header menu.
+ *
+ * @author Dirk Fauth
+ *
+ */
+public class _532_GlazedListsRowHideShowExample extends AbstractNatExample {
+
+ public static void main(String[] args) throws Exception {
+ StandaloneNatExampleRunner.run(new _532_GlazedListsRowHideShowExample());
+ }
+
+ @Override
+ public String getDescription() {
+ return "This example shows the usage of the row hide/show functionality within a grid and "
+ + "its corresponding actions in the row header menu using the GlazedLists extension. "
+ + "If you perform a right click on the row header, you are able to hide the current selected "
+ + "row or show all rows again.";
+ }
+
+ @Override
+ public Control createExampleControl(Composite parent) {
+ //property names of the Person class
+ String[] propertyNames = {"firstName", "lastName", "gender", "married", "birthday"};
+
+ //mapping from property to label, needed for column header labels
+ Map<String, String> propertyToLabelMap = new HashMap<String, String>();
+ propertyToLabelMap.put("firstName", "Firstname");
+ propertyToLabelMap.put("lastName", "Lastname");
+ propertyToLabelMap.put("gender", "Gender");
+ propertyToLabelMap.put("married", "Married");
+ propertyToLabelMap.put("birthday", "Birthday");
+
+ //build the body layer stack
+ //Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
+ //setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
+ //directly as body layer is also working.
+
+ //first wrap the base list in a GlazedLists EventList and a FilterList so it is possible to filter
+ EventList<Person> eventList = GlazedLists.eventList(PersonService.getPersons(10));
+ FilterList<Person> filterList = new FilterList<Person>(eventList);
+
+ //use the GlazedListsDataProvider for some performance tweaks
+ final IRowDataProvider<Person> bodyDataProvider = new GlazedListsDataProvider<Person>(filterList,
+ new ReflectiveColumnPropertyAccessor<Person>(propertyNames));
+ //create the IRowIdAccessor that is necessary for row hide/show
+ final IRowIdAccessor<Person> rowIdAccessor = new IRowIdAccessor<Person>() {
+ @Override
+ public Serializable getRowId(Person rowObject) {
+ return rowObject.getId();
+ }
+ };
+
+ DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
+
+ //add a GlazedLists event layer that is responsible for updating the grid on list changes
+ DetailGlazedListsEventLayer<Person> glazedListsEventLayer =
+ new DetailGlazedListsEventLayer<Person>(bodyDataLayer, filterList);
+
+ GlazedListsRowHideShowLayer<Person> rowHideShowLayer = new GlazedListsRowHideShowLayer<Person>(
+ glazedListsEventLayer, bodyDataProvider, rowIdAccessor, filterList);
+
+ SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
+ ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
+
+ //build the column header layer
+ IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
+ DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
+ ILayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
+
+ //build the row header layer
+ IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
+ DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
+ ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);
+
+ //build the corner layer
+ IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
+ DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
+ ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnHeaderLayer);
+
+ //build the grid layer
+ GridLayer gridLayer = new GridLayer(viewportLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);
+
+ //turn the auto configuration off as we want to add our header menu configuration
+ NatTable natTable = new NatTable(parent, gridLayer, false);
+
+ //as the autoconfiguration of the NatTable is turned off, we have to add the
+ //DefaultNatTableStyleConfiguration manually
+ natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
+
+ //add the header menu configuration for adding the column header menu with hide/show actions
+ natTable.addConfiguration(new AbstractHeaderMenuConfiguration(natTable) {
+
+ @Override
+ protected PopupMenuBuilder createRowHeaderMenu(NatTable natTable) {
+ return new PopupMenuBuilder(natTable)
+ .withHideRowMenuItem()
+ .withShowAllRowsMenuItem();
+ }
+
+ @Override
+ protected PopupMenuBuilder createCornerMenu(NatTable natTable) {
+ return super.createCornerMenu(natTable)
+ .withHideRowMenuItem();
+ }
+ });
+ natTable.configure();
+
+ return natTable;
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
index bb8747f..4ac3ac4 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/ExtendedPersonWithAddress.java
@@ -29,11 +29,11 @@
private String filename;
@SuppressWarnings("deprecation")
- public ExtendedPersonWithAddress(String firstName, String lastName,
+ public ExtendedPersonWithAddress(int id, String firstName, String lastName,
Gender gender, boolean married, Date birthday, Address address,
String password, String description, double money, List<String> favouriteFood,
List<String> favouriteDrinks) {
- super(firstName, lastName, gender, married, birthday, address);
+ super(id, firstName, lastName, gender, married, birthday, address);
this.password = password;
this.description = description;
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
index 88999d4..a46257e 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/Person.java
@@ -7,15 +7,19 @@
MALE, FEMALE
}
+ private final int id;
private String firstName;
private String lastName;
private Gender gender;
private boolean married;
private Date birthday;
- public Person() { }
+ public Person(int id) {
+ this.id = id;
+ }
- public Person(String firstName, String lastName, Gender gender, boolean married, Date birthday) {
+ public Person(int id, String firstName, String lastName, Gender gender, boolean married, Date birthday) {
+ this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
@@ -24,6 +28,13 @@
}
/**
+ * @return the id
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
* @return the firstName
*/
public String getFirstName() {
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
index 0bb10f5..22a8b07 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonService.java
@@ -27,7 +27,7 @@
List<Person> result = new ArrayList<Person>();
for (int i = 0; i < numberOfPersons; i++) {
- result.add(createPerson());
+ result.add(createPerson(i));
}
return result;
@@ -42,7 +42,7 @@
List<PersonWithAddress> result = new ArrayList<PersonWithAddress>();
for (int i = 0; i < numberOfPersons; i++) {
- result.add(new PersonWithAddress(createPerson(), createAddress()));
+ result.add(new PersonWithAddress(createPerson(i), createAddress()));
}
return result;
@@ -57,7 +57,7 @@
List<ExtendedPersonWithAddress> result = new ArrayList<ExtendedPersonWithAddress>();
for (int i = 0; i < numberOfPersons; i++) {
- result.add(new ExtendedPersonWithAddress(createPerson(), createAddress(),
+ result.add(new ExtendedPersonWithAddress(createPerson(i), createAddress(),
generateSimplePassword(), createRandomLengthText(), createRandomMoneyAmount(),
createFavouriteFood(), createFavouriteDrinks()));
}
@@ -70,14 +70,14 @@
* and enrich them with random generated married state and birthday date.
* @return
*/
- private static Person createPerson() {
+ private static Person createPerson(int id) {
String[] maleNames = {"Bart", "Homer", "Lenny", "Carl", "Waylon", "Ned", "Timothy"};
String[] femaleNames = {"Marge", "Lisa", "Maggie", "Edna", "Helen", "Jessica"};
String[] lastNames = {"Simpson", "Leonard", "Carlson", "Smithers", "Flanders", "Krabappel", "Lovejoy"};
Random randomGenerator = new Random();
- Person result = new Person();
+ Person result = new Person(id);
result.setGender(Gender.values()[randomGenerator.nextInt(2)]);
if (result.getGender().equals(Gender.MALE)) {
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
index 1e07498..4979dec 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/data/person/PersonWithAddress.java
@@ -7,14 +7,14 @@
private Address address;
- public PersonWithAddress(String firstName, String lastName, Gender gender,
+ public PersonWithAddress(int id, String firstName, String lastName, Gender gender,
boolean married, Date birthday, Address address) {
- super(firstName, lastName, gender, married, birthday);
+ super(id, firstName, lastName, gender, married, birthday);
this.address = address;
}
public PersonWithAddress(Person person, Address address) {
- super(person.getFirstName(), person.getLastName(), person.getGender(),
+ super(person.getId(), person.getFirstName(), person.getLastName(), person.getGender(),
person.isMarried(), person.getBirthday());
this.address = address;
}
diff --git a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
index 26f4e0c..6d4ea20 100644
--- a/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
+++ b/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/examples/_100_Layers/TreeGridExample.java
@@ -28,7 +28,7 @@
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsDataProvider;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.NewGlazedListsEventLayer;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.DetailGlazedListsEventLayer;
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.grid.data.DefaultColumnHeaderDataProvider;
@@ -104,8 +104,8 @@
// GlazedListsEventLayer<Datum> glazedListsEventLayer =
// new GlazedListsEventLayer<Datum>(bodyDataLayer, treeList);
- NewGlazedListsEventLayer<Datum> glazedListsEventLayer =
- new NewGlazedListsEventLayer<Datum>(bodyDataLayer, treeList);
+ DetailGlazedListsEventLayer<Datum> glazedListsEventLayer =
+ new DetailGlazedListsEventLayer<Datum>(bodyDataLayer, treeList);
// Body layer
ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(glazedListsEventLayer);
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 8a216b0..3d4e19f 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 @@
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.hideshow,
org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree
Import-Package: ca.odell.glazedlists,
ca.odell.glazedlists.event,
@@ -34,6 +35,7 @@
org.eclipse.nebula.widgets.nattable.grid.data,
org.eclipse.nebula.widgets.nattable.grid.layer,
org.eclipse.nebula.widgets.nattable.hideshow,
+ org.eclipse.nebula.widgets.nattable.hideshow.command,
org.eclipse.nebula.widgets.nattable.hideshow.event,
org.eclipse.nebula.widgets.nattable.layer,
org.eclipse.nebula.widgets.nattable.layer.cell,
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
similarity index 75%
rename from org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java
rename to org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
index 9ce17c7..e1f37b4 100644
--- a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/NewGlazedListsEventLayer.java
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/DetailGlazedListsEventLayer.java
@@ -32,13 +32,30 @@
import ca.odell.glazedlists.event.ListEventListener;
/**
+ * This layer acts as the event listener for:
+ * <ol>
+ * <li>Glazed list events - {@link ListEvent}
+ * <li>Bean updates - PropertyChangeEvent(s)
+ * </ol>
+ *
+ * Compared to the GlazedListsEventLayer, this layer does not conflate events and only
+ * fire a single RowStructuralRefreshEvent for all events within 100ms. Instead it will
+ * fire a corresponding NatTable event with the detail information for every {@link ListEvent}
+ * fired by the GlazedLists immediately.
+ *
+ * @param <T> Type of the bean in the backing list.
+ *
* @author Dirk Fauth
*
*/
-public class NewGlazedListsEventLayer<T> extends AbstractLayerTransform
+public class DetailGlazedListsEventLayer<T> extends AbstractLayerTransform
implements IUniqueIndexLayer, ListEventListener<T>, PropertyChangeListener {
- private static final Scheduler scheduler = new Scheduler(NewGlazedListsEventLayer.class.getSimpleName());
+ /**
+ * The scheduler needed to add cleanup tasks which are scheduled after handling
+ * glazedlists events.
+ */
+ private static final Scheduler scheduler = new Scheduler(DetailGlazedListsEventLayer.class.getSimpleName());
/**
* The underlying layer of type {@link IUniqueIndexLayer}
@@ -57,16 +74,27 @@
*/
private EventList<T> eventList;
-
+ /**
+ * The {@link ListEvent} that was handled before. Needed to ensure that the same event
+ * is not processed several times. Will be reset by the cleanup task 100ms after the handling.
+ */
private ListEvent<T> lastFiredEvent;
-
+ /**
+ * The current scheduled cleanup task which is stored to ensure that at most only one cleanup
+ * task is active at any time and it can be stopped if the NatTable itself is disposed to avoid
+ * still active background tasks that get never be done.
+ */
private ScheduledFuture<?> cleanupFuture;
/**
- * @param underlyingLayer
+ * Create a new {@link DetailGlazedListsEventLayer} which is in fact a {@link ListEventListener}
+ * that listens to GlazedLists events and translate them into events that are understandable
+ * by the NatTable.
+ * @param underlyingLayer The underlying layer of type {@link IUniqueIndexLayer}
+ * @param eventList The {@link EventList} this layer should be added as listener.
*/
- public NewGlazedListsEventLayer(IUniqueIndexLayer underlyingLayer, EventList<T> eventList) {
+ public DetailGlazedListsEventLayer(IUniqueIndexLayer underlyingLayer, EventList<T> eventList) {
super(underlyingLayer);
this.underlyingLayer = underlyingLayer;
@@ -115,7 +143,7 @@
cleanupFuture = scheduler.schedule(new Runnable() {
@Override
public void run() {
- NewGlazedListsEventLayer.this.lastFiredEvent = null;
+ DetailGlazedListsEventLayer.this.lastFiredEvent = null;
}
}, 100L);
}
@@ -126,7 +154,7 @@
public boolean doCommand(ILayerCommand command) {
if (command instanceof DisposeResourcesCommand) {
//ensure to kill a possible running cleanup task
- if (cleanupFuture == null || cleanupFuture.isDone() || cleanupFuture.isCancelled()) {
+ if (cleanupFuture != null && !cleanupFuture.isDone() && !cleanupFuture.isCancelled()) {
scheduler.unschedule(cleanupFuture);
}
}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java
new file mode 100644
index 0000000..3d89ea7
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowHideCommandHandler.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiRowHideCommand;
+
+/**
+ * Command handler for handling {@link MultiRowHideCommand}s in a NatTable that uses GlazedLists.
+ *
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsMultiRowHideCommandHandler<T> extends AbstractLayerCommandHandler<MultiRowHideCommand>{
+
+ /**
+ * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+ /**
+ *
+ * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ public GlazedListsMultiRowHideCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+ this.rowHideShowLayer = rowHideShowLayer;
+ }
+
+ @Override
+ public Class<MultiRowHideCommand> getCommandClass() {
+ return MultiRowHideCommand.class;
+ }
+
+ @Override
+ protected boolean doCommand(MultiRowHideCommand command) {
+ rowHideShowLayer.hideRowPositions(command.getRowPositions());
+ return true;
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java
new file mode 100644
index 0000000..c78c3ac
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsMultiRowShowCommandHandler.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.MultiRowShowCommand;
+
+/**
+ * Command handler for handling {@link MultiRowShowCommand}s in a NatTable that uses GlazedLists.
+ *
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsMultiRowShowCommandHandler<T> extends AbstractLayerCommandHandler<MultiRowShowCommand> {
+
+ /**
+ * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+ /**
+ *
+ * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ public GlazedListsMultiRowShowCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+ this.rowHideShowLayer = rowHideShowLayer;
+ }
+
+ @Override
+ public Class<MultiRowShowCommand> getCommandClass() {
+ return MultiRowShowCommand.class;
+ }
+
+ @Override
+ protected boolean doCommand(MultiRowShowCommand command) {
+ rowHideShowLayer.showRowIndexes(command.getRowIndexes());
+ return true;
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java
new file mode 100644
index 0000000..d07e4a0
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideCommandHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import static java.util.Arrays.asList;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.RowHideCommand;
+
+/**
+ * Command handler for handling {@link RowHideCommand}s in a NatTable that uses GlazedLists.
+ *
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsRowHideCommandHandler<T> extends AbstractLayerCommandHandler<RowHideCommand> {
+
+ /**
+ * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+ /**
+ *
+ * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ public GlazedListsRowHideCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+ this.rowHideShowLayer = rowHideShowLayer;
+ }
+
+ @Override
+ public Class<RowHideCommand> getCommandClass() {
+ return RowHideCommand.class;
+ }
+
+ @Override
+ protected boolean doCommand(RowHideCommand command) {
+ rowHideShowLayer.hideRowPositions(asList(command.getRowPosition()));
+ return true;
+ }
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java
new file mode 100644
index 0000000..9d3c876
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsRowHideShowLayer.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.nebula.widgets.nattable.command.ILayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
+
+import ca.odell.glazedlists.FilterList;
+import ca.odell.glazedlists.matchers.AbstractMatcherEditor;
+import ca.odell.glazedlists.matchers.CompositeMatcherEditor;
+import ca.odell.glazedlists.matchers.Matcher;
+import ca.odell.glazedlists.matchers.MatcherEditor;
+
+/**
+ * Adds the functionality for manually hiding rows in a NatTable that is based on GlazedLists.
+ * Technically it will filter items by id in the {@link FilterList}.
+ * <p>
+ * Note: If you want to add row hide/show AND filtering to your NatTable, you need to use the
+ * DefaultGlazedListsStaticFilterStrategy and add the {@link Matcher} that is used by
+ * this command as a static {@link MatcherEditor}. Otherwise these two functions will not work
+ * correctly together.
+ *
+ * @author Dirk Fauth
+ *
+ * TODO add IPersistable
+ */
+public class GlazedListsRowHideShowLayer<T> extends AbstractLayerTransform implements IUniqueIndexLayer {
+
+ /**
+ * The collection of row id's that are hidden.
+ */
+ private final Set<Serializable> rowIdsToHide = new HashSet<Serializable>();
+
+ /**
+ * The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+ * This is necessary to determine the row object to hide in terms of content.
+ */
+ private final IRowIdAccessor<T> rowIdAccessor;
+
+ /**
+ * The {@link IRowDataProvider} needed to get the object at a given position so it
+ * is possible to retrieve the id that is used for filtering.
+ */
+ private final IRowDataProvider<T> rowDataProvider;
+
+ /**
+ * The {@link MatcherEditor} that is used to filter the rows with the specified id's.
+ */
+ private final HideRowMatcherEditor hideRowByIdMatcherEditor = new HideRowMatcherEditor();
+
+ /**
+ * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+ * NatTables. Using this constructor will only instantiate this layer. To use this correctly
+ * you need to register the local row hide {@link MatcherEditor} against the {@link FilterList} yourself.
+ * @param underlyingLayer The underlying layer.
+ * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+ * is possible to retrieve the id that is used for filtering.
+ * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+ * This is necessary to determine the row object to hide in terms of content.
+ */
+ public GlazedListsRowHideShowLayer(
+ ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor) {
+ super(underlyingLayer);
+ if (rowIdAccessor == null) {
+ throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+ }
+
+ this.rowDataProvider = rowDataProvider;
+ this.rowIdAccessor = rowIdAccessor;
+
+ registerCommandHandlers();
+ }
+
+ /**
+ * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+ * NatTables. Using this constructor will add the {@link MatcherEditor} to the given {@link FilterList}.
+ * This might not work correctly in combination with other filters like e.g. the filter row.
+ * @param underlyingLayer The underlying layer.
+ * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+ * is possible to retrieve the id that is used for filtering.
+ * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+ * This is necessary to determine the row object to hide in terms of content.
+ * @param filterList The {@link FilterList} to apply the local row hide {@link Matcher} to.
+ */
+ public GlazedListsRowHideShowLayer(
+ ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor, FilterList<T> filterList) {
+ super(underlyingLayer);
+ if (rowIdAccessor == null) {
+ throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+ }
+ if (filterList == null) {
+ throw new IllegalArgumentException("filterList can not be null!"); //$NON-NLS-1$
+ }
+
+ this.rowDataProvider = rowDataProvider;
+ this.rowIdAccessor = rowIdAccessor;
+
+ filterList.setMatcherEditor(this.hideRowByIdMatcherEditor);
+
+ registerCommandHandlers();
+ }
+
+ /**
+ * Creates a {@link GlazedListsRowHideShowLayer} for adding row hide/show for GlazedLists based
+ * NatTables. Using this constructor will add the {@link MatcherEditor} to the given
+ * {@link CompositeMatcherEditor}. This way it is possible to add more filter logic than only the
+ * row hide filter.
+ * @param underlyingLayer The underlying layer.
+ * @param rowDataProvider The {@link IRowDataProvider} needed to get the object at a given position so it
+ * is possible to retrieve the id that is used for filtering.
+ * @param rowIdAccessor The {@link IRowIdAccessor} that is used to extract the id out of the row object.
+ * This is necessary to determine the row object to hide in terms of content.
+ * @param matcherEditor The {@link CompositeMatcherEditor} to which the local row hide {@link Matcher}
+ * should be added.
+ */
+ public GlazedListsRowHideShowLayer(
+ ILayer underlyingLayer, IRowDataProvider<T> rowDataProvider, IRowIdAccessor<T> rowIdAccessor, CompositeMatcherEditor<T> matcherEditor) {
+ super(underlyingLayer);
+ if (rowIdAccessor == null) {
+ throw new IllegalArgumentException("rowIdAccessor can not be null!"); //$NON-NLS-1$
+ }
+ if (matcherEditor == null) {
+ throw new IllegalArgumentException("matcherEditor can not be null!"); //$NON-NLS-1$
+ }
+
+ this.rowDataProvider = rowDataProvider;
+ this.rowIdAccessor = rowIdAccessor;
+
+ matcherEditor.getMatcherEditors().add(this.hideRowByIdMatcherEditor);
+
+ registerCommandHandlers();
+ }
+
+ /**
+ * Register the {@link ILayerCommandHandler} that will handle the row hide/show events
+ * for this layer.
+ */
+ protected void registerCommandHandlers() {
+ registerCommandHandler(new GlazedListsRowHideCommandHandler<T>(this));
+ registerCommandHandler(new GlazedListsMultiRowHideCommandHandler<T>(this));
+ registerCommandHandler(new GlazedListsShowAllRowsCommandHandler<T>(this));
+ registerCommandHandler(new GlazedListsMultiRowShowCommandHandler<T>(this));
+ }
+
+ /**
+ * Hide the rows at the given positions. Will collect the id's of the rows at
+ * the given positions as this layer operates on content rather than positions.
+ * @param rowPositions The positions of the rows to hide.
+ */
+ public void hideRowPositions(Collection<Integer> rowPositions) {
+ Collection<Serializable> rowIds = new HashSet<Serializable>();
+ for (Integer rowPos : rowPositions) {
+ int rowIndex = getRowIndexByPosition(rowPos);
+ rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+ }
+ hideRows(rowIds);
+ }
+
+ /**
+ * Hide the rows at the given indexes. Will collect the id's of the rows at
+ * the given positions as this layer operates on content rather than positions.
+ * @param rowIndexes The indexes of the rows to hide.
+ */
+ public void hideRowIndexes(Collection<Integer> rowIndexes) {
+ Collection<Serializable> rowIds = new HashSet<Serializable>();
+ for (Integer rowIndex : rowIndexes) {
+ rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+ }
+ hideRows(rowIds);
+ }
+
+ /**
+ * Show the rows with the given indexes again. Will collect the id's of the rows at
+ * the given positions as this layer operates on content rather than positions.
+ * @param rowIndexes The indexes of the rows that should be showed again.
+ */
+ public void showRowIndexes(Collection<Integer> rowIndexes) {
+ Collection<Serializable> rowIds = new HashSet<Serializable>();
+ for (Integer rowIndex : rowIndexes) {
+ rowIds.add(rowIdAccessor.getRowId(rowDataProvider.getRowObject(rowIndex)));
+ }
+ showRows(rowIds);
+ }
+
+ /**
+ * Hide the rows that contain the objects with the given row ids.
+ * @param rowIds The row ids of the rows that should be hidden.
+ */
+ public void hideRows(Collection<Serializable> rowIds) {
+ this.rowIdsToHide.addAll(rowIds);
+ this.hideRowByIdMatcherEditor.fireChange();
+ }
+
+ /**
+ * Show the rows that contain the objects with the given row ids.
+ * Will of course only have impact if those rows are currently hidden.
+ * @param rowIds The row ids of the rows that should be showed.
+ */
+ public void showRows(Collection<Serializable> rowIds) {
+ this.rowIdsToHide.removeAll(rowIds);
+ this.hideRowByIdMatcherEditor.fireChange();
+ }
+
+ /**
+ * Show all rows that where previously hidden.
+ */
+ public void showAllRows() {
+ this.rowIdsToHide.clear();
+ this.hideRowByIdMatcherEditor.fireChange();
+ }
+
+ /**
+ * @return The {@link MatcherEditor} that is used to filter the rows with the specified id's.
+ */
+ public MatcherEditor<T> getMatcherEditor() {
+ return this.hideRowByIdMatcherEditor;
+ }
+
+ @Override
+ public int getColumnPositionByIndex(int columnIndex) {
+ return ((IUniqueIndexLayer) getUnderlyingLayer()).getColumnPositionByIndex(columnIndex);
+ }
+
+ @Override
+ public int getRowPositionByIndex(int rowIndex) {
+ return ((IUniqueIndexLayer) getUnderlyingLayer()).getRowPositionByIndex(rowIndex);
+ }
+
+ /**
+ * {@link MatcherEditor} implementation that will only match objects that are not hidden by
+ * id. It also enables to fire change events to indicate changes to the filter.
+ *
+ * @author Dirk Fauth
+ *
+ */
+ class HideRowMatcherEditor extends AbstractMatcherEditor<T> {
+ /**
+ * The {@link Matcher} that is used to filter the rows with the specified id's.
+ */
+ private final Matcher<T> hideRowByIdMatcher = new Matcher<T>() {
+ @Override
+ public boolean matches(T rowObject) {
+ return !rowIdsToHide.contains(rowIdAccessor.getRowId(rowObject));
+ }
+ };
+
+ @Override
+ public Matcher<T> getMatcher() {
+ return this.hideRowByIdMatcher;
+ }
+
+ /**
+ * Fire a change so the listeners can be informed about a change for the {@link Matcher}
+ */
+ public void fireChange() {
+ fireChanged(this.hideRowByIdMatcher);
+ }
+ }
+
+}
diff --git a/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java
new file mode 100644
index 0000000..9a1e021
--- /dev/null
+++ b/org.eclipse.nebula.widgets.nattable.extension.glazedlists/src/org/eclipse/nebula/widgets/nattable/extension/glazedlists/hideshow/GlazedListsShowAllRowsCommandHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Dirk Fauth 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:
+ * Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.nebula.widgets.nattable.extension.glazedlists.hideshow;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.hideshow.command.ShowAllRowsCommand;
+
+/**
+ * Command handler to show all rows again that are currently hidden in the context of
+ * using GlazedLists.
+ *
+ * @author Dirk Fauth
+ *
+ */
+public class GlazedListsShowAllRowsCommandHandler<T> extends AbstractLayerCommandHandler<ShowAllRowsCommand> {
+
+ /**
+ * The {@link GlazedListsRowHideShowLayer} where this command handler should operate on.
+ */
+ private final GlazedListsRowHideShowLayer<T> rowHideShowLayer;
+
+ /**
+ *
+ * @param rowHideShowLayer The {@link GlazedListsRowHideShowLayer} to operate on.
+ */
+ public GlazedListsShowAllRowsCommandHandler(GlazedListsRowHideShowLayer<T> rowHideShowLayer) {
+ this.rowHideShowLayer = rowHideShowLayer;
+ }
+
+ @Override
+ public Class<ShowAllRowsCommand> getCommandClass() {
+ return ShowAllRowsCommand.class;
+ }
+
+ @Override
+ protected boolean doCommand(ShowAllRowsCommand command) {
+ rowHideShowLayer.showAllRows();
+ return true;
+ }
+
+}