I try to implement a simple filterrow with glazedlists. The filterrow appears and I can put my filter-string into the textfields. Until then everything works fine but on pressing enter, nothing happens. No filtering.
Mostly I followed the example in: [1] https://github.com/eclipse/nebula.widgets.nattable/blob/master/org.eclipse.nebula.widgets.nattable.examples/src/org/eclipse/nebula/widgets/nattable/examples/_600_GlazedLists/_603_Filter/_6031_GlazedListsFilterExample.java
I also read following article: [2] http://www.eclipse.org/nattable/resources/NatTable_Advanced.pdf
Now to my implementation:
As described in [1] I packed the data-list into a filterList before it is passed to the DataProvider. After that I built my bodyLayerStack with the GlazedListsEventLayer.
EventList<T> eventList = GlazedLists.eventList(entries);
TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
filterList = new FilterList<T>(sortedList);
bodyDataProvider = new LogListDataProvider<>(filterList, columnPropertyAccessor);
DataLayer bodyDataLayer = new DataLayer(getBodyDataProvider());
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(bodyDataLayer, filterList);
ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(glazedListsEventLayer);
ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
selectionLayer = new SelectionLayer(columnHideShowLayer, false);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
The used class 'LogListDataProvider' is just an extension to the ListDataProvider, I only added a setter-method 'setList(List list)' because I refresh the table after creating with its content.
public class LogListDataProvider<T> extends ListDataProvider<T> {
public LogListDataProvider(List<T> list, IColumnAccessor<T> columnAccessor) {
super(list, columnAccessor);
}
public void setList(List<T> list) {
this.list = list;
}
}
For the FilterRowHeader I also followed example [1] and build an FilterRowHeaderComposite.
FilterRowHeaderComposite<LogEntry> filterRowHeaderComposite = new FilterRowHeaderComposite<LogEntry>(
new DefaultGlazedListsFilterStrategy<LogEntry>(bodyLayerStack.getFilterList(),
columnPropertyAccessor, configRegistry),
columnHeaderLayer, columnHeaderDataLayer.getDataProvider(), configRegistry);
// Columns: 1 ; Rows: 2
CompositeLayer compositeLayer = new CompositeLayer(1, 2);
compositeLayer.addConfiguration(new DefaultGridLayerConfiguration(compositeLayer));
// add headerlayer-stack and bodylayer-stack to compositelayer
compositeLayer.setChildLayer(GridRegion.COLUMN_HEADER, filterRowHeaderComposite, 0, 0);
compositeLayer.setChildLayer(GridRegion.BODY, bodyLayerStack, 0, 1);
For me it seems that I followed [1] and [2] correctly, but although it is not working.
The issue seems to be your way to exchange the content via setList(). The filter logic is bound to the first list at creation of the DefaultGlazedListsFilterStrategy. Now you exchange the content in the body via setList() but the filter still operates on the old list.
Because of these facts the typical way to exchange data in a NatTable is to clear and add new content on the original list. Note that in case of big datasets you should disable the event layer before such a change and enable it afterwards again to avoid race conditions regarding updates and event processing.
I'm not sure if we also support changing the list in the filter strategy. That could be another option. But I'm not sure if that would work because of other conditions.