Home » Eclipse Projects » NatTable » How to update row group header while filtering
How to update row group header while filtering [message #1855887] |
Tue, 08 November 2022 16:47  |
Eclipse User |
|
|
|
Hi,
I am using row group header in nattable. The nattable is updating properly when filter applies, but the corresponding row group header not updating.
Please find attachments before filter and after filter images.
"1" means green clor and "2" means red color.
"506" row header is red color actually.
After filtering with "1", table is filtering properly, but the row header not updating and its always showing the default order like without filter.
Could you please guide me how to fix this issue.
Thanks in Advance.
|
|
| |
Re: How to update row group header while filtering [message #1855903 is a reply to message #1855893] |
Wed, 09 November 2022 04:51   |
Eclipse User |
|
|
|
Hello Dirk,
I am using dynamic columns. Please find the code below and please let me know if i am wrong somewhere.
// add row values
for (int i = 0; i < finalRows.size(); i++) {
values.add(createValueRow(rowMap.get(i)));
}
private Map createValueRow(String rowValue) {
Map valueRow = new HashMap<>();
for (int i = 0; i < finalColumns.size(); i++) {
String colActual = columnMap.get(i);
valueRow.put(i, resultCheckSatMap.get(colActual + "+" + rowValue));
}
return valueRow;
}
// create configregistry
ConfigRegistry configRegistry = new ConfigRegistry();
// create the body layer stack
BodyLayerStack bodyLayerStack = new BodyLayerStack(values, new MyColumnPropertyAccessor(), configRegistry);
// setting column Widths
setColumnWidth(bodyLayerStack.getBodyDataLayer());
// create the column header layer stack
IDataProvider columnHeaderDataProvider = new SimpleColumnHeaderDataProvider(finalColumns);
DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayerStack.getViewportLayer(), bodyLayerStack.getSelectionLayer());
columnGroupHeaderLayer = new ColumnGroupHeaderLayer(columnHeaderLayer, bodyLayerStack.getSelectionLayer());
// create the row header layer stack
IDataProvider rowHeaderDataProvider = new SimpleRowHeaderDataProvider(bodyLayerStack.getBodyDataProvider(), finalRows);
DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
rowHeaderDataLayer.setColumnWidthByPosition(0, calculateMaxString(finalRows) * 7);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayerStack, bodyLayerStack.getSelectionLayer());
rowGroupHeaderLayer = new RowGroupHeaderLayer(rowHeaderLayer, bodyLayerStack.getSelectionLayer());
rowGroupHeaderLayer.addConfiguration(new DefaultRowGroupHeaderLayerConfiguration(true));
// add the filter row functionality
final FilterRowHeaderComposite<HierarchicalWrapper> filterRowHeaderLayer = new FilterRowHeaderComposite<>(new DefaultGlazedListsFilterStrategy<>(bodyLayerStack.getFilterList(), bodyLayerStack.getColumnPropertyAccessor(), configRegistry), sortHeaderLayer, columnHeaderDataProvider, configRegistry);
// create the corner layer stack
ILayer cornerLayer = new CornerLayer(new DataLayer(new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)), rowGroupHeaderLayer, filterRowHeaderLayer);
// create the composite layer composed with the prior created layer stacks
CompositeLayer compositeLayer = new CompositeLayer(2, 2);
compositeLayer.setChildLayer(GridRegion.CORNER, cornerLayer, 0, 0);
compositeLayer.setChildLayer(GridRegion.COLUMN_HEADER, filterRowHeaderLayer, 1, 0);
compositeLayer.setChildLayer(GridRegion.ROW_HEADER, rowGroupHeaderLayer, 0, 1);
compositeLayer.setChildLayer(GridRegion.BODY, bodyLayerStack, 1, 1);
compositeLayer.addConfiguration(new DefaultEditConfiguration());
// create nattable
natTable = new NatTable(natContainer, compositeLayer, false);
natTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
class BodyLayerStack extends AbstractLayerTransform {
private final FilterList filterList;
private final IRowDataProvider bodyDataProvider;
private final SelectionLayer selectionLayer;
private final ViewportLayer viewportLayer;
private final DataLayer bodyDataLayer;
private final IColumnPropertyAccessor columnPropertyAccessor;
private final SortedList sortedList;
private ColumnGroupExpandCollapseLayer columnGroupExpandCollapseLayer;
private ColumnGroupModel columnGroupModel;
private RowGroupExpandCollapseLayer rowGroupExpandCollapseLayer;
public BodyLayerStack(List values, IColumnPropertyAccessor columnPropertyAccessor, ConfigRegistry configRegistry) {
this.columnPropertyAccessor = columnPropertyAccessor;
EventList eventList = GlazedLists.eventList(values);
TransformedList rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
sortedList = new SortedList<>(rowObjectsGlazedList, null);
this.filterList = new FilterList<>(sortedList);
this.bodyDataProvider = new ListDataProvider<>(this.filterList, this.columnPropertyAccessor);
bodyDataLayer = new DataLayer(getBodyDataProvider());
bodyDataLayer.setConfigLabelAccumulator(new ColumnLabelAccumulator());
columnGroupExpandCollapseLayer = new ColumnGroupExpandCollapseLayer(bodyDataLayer);
rowGroupExpandCollapseLayer = new RowGroupExpandCollapseLayer(columnGroupExpandCollapseLayer);
HoverLayer hoverLayer = new HoverLayer(rowGroupExpandCollapseLayer, true);
hoverLayer.addConfiguration(new SimpleHoverStylingBindings(hoverLayer));
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer glazedListsEventLayer = new GlazedListsEventLayer<>(hoverLayer, this.filterList);
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
public SortedList getSortedList() {
return sortedList;
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
public FilterList getFilterList() {
return this.filterList;
}
public IRowDataProvider getBodyDataProvider() {
return this.bodyDataProvider;
}
public ViewportLayer getViewportLayer() {
return this.viewportLayer;
}
public IColumnPropertyAccessor getColumnPropertyAccessor() {
return this.columnPropertyAccessor;
}
public DataLayer getBodyDataLayer() {
return this.bodyDataLayer;
}
public ColumnGroupExpandCollapseLayer getColumnGroupExpandCollapseLayer() {
return columnGroupExpandCollapseLayer;
}
}
class MyColumnPropertyAccessor implements IColumnPropertyAccessor {
@Override
public Object getDataValue(Object rowObj, int columnIndex) {
if (rowObj instanceof Map)
return ((Map) rowObj).get(columnIndex);
else
return null;
}
@Override
public void setDataValue(Object rowObj, int columnIndex, Object newValue) {
if (rowObj instanceof Map)
if (newValue instanceof Image) {
((Map) rowObj).put(getColumnProperty(columnIndex), newValue);
} else {
((Map) rowObj).put(getColumnProperty(columnIndex), newValue.toString());
}
}
@Override
public int getColumnCount() {
return CapeGroupExpertSatisfiabilityNattableViewer.this.finalColumns.size();
}
@Override
public String getColumnProperty(int columnIndex) {
return (String) CapeGroupExpertSatisfiabilityNattableViewer.this.finalColumns.get(columnIndex);
}
@Override
public int getColumnIndex(String propertyName) {
return CapeGroupExpertSatisfiabilityNattableViewer.this.finalColumns.indexOf(propertyName);
}
}
class SimpleColumnHeaderDataProvider implements IDataProvider {
List columns = new ArrayList<>();
public SimpleColumnHeaderDataProvider(List columns) {
this.columns = columns;
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return this.columns.get(columnIndex);
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
throw new UnsupportedOperationException();
}
@Override
public int getColumnCount() {
return CapeGroupExpertSatisfiabilityNattableViewer.this.finalColumns.size();
}
@Override
public int getRowCount() {
return 1;
}
}
public class SimpleRowHeaderDataProvider implements IDataProvider {
private final IDataProvider bodyDataProvider;
private final List<String> finalRowList;
public SimpleRowHeaderDataProvider(IDataProvider bodyDataProvider, List<String> finalRowList) {
this.bodyDataProvider = bodyDataProvider;
this.finalRowList = finalRowList;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public int getRowCount() {
return this.bodyDataProvider.getRowCount();
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return getRowHeaderLabel(rowIndex);
}
public String getRowHeaderLabel(int rowIndex) {
if (finalRowList != null && !finalRowList.isEmpty() && rowIndex != -1)
return finalRowList.get(rowIndex);
else
return null;
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
throw new UnsupportedOperationException();
}
}
|
|
| | |
Re: How to update row group header while filtering [message #1855927 is a reply to message #1855922] |
Thu, 10 November 2022 00:37   |
Eclipse User |
|
|
|
I don't understand why it is necessary for you to retrieve the information from the base list. If this is really necessary IMHO you have an incorrect design for your table.
Two things to understand:
1. NatTable is doing transformations via layers, so you have a position-index transformation and NatTable is able to provide a back and forth transformation if the layers support this. But you can at least always get the index from a position.
2. GlazedLists is also providing a transformation, but on the level of the list. And as it is an abstracted view on the base list, there is no way to get the index of an element from the base collection. Despite you are using indexOf() which is not a quite good choice if you need to do this in every rendering processing as it has not so good performance stats.
3. For NatTable only the list that is used to show the content matters, in the case of GlazedLists that is the top most list, e.g. FilterList. So you actually only need to get the information from the row object via the row position in the row header data provider and use that to access the body data provider.
The NatTable examples you are referring to show example the same behaviour that you face, because of the same situation. They use the DefaultRowHeaderDataProvider that is simply showing the row number. And that changes as the FilterList changes the content. There is no connection to the body content, only to the body structure. The number that is shown actually IS the row index + 1, but from the FilterList and not the base list.
Assuming the body data provider is a ListDataProvider and the row object has a getId() method, the row header data provider could look like this:
IDataProvider rowHeaderDataProvider =
new IDataProvider() {
@Override
public int getColumnCount() {
return 1;
}
@Override
public int getRowCount() {
return bodyLayerStack.getBodyDataProvider().getRowCount();
}
@Override
public Object getDataValue(int columnIndex, int rowIndex) {
return bodyLayerStack.getBodyDataProvider().getRowObject(rowIndex).getId();
}
@Override
public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
throw new UnsupportedOperationException();
}
};
|
|
| |
Goto Forum:
Current Time: Sat May 24 07:14:10 EDT 2025
Powered by FUDForum. Page generated in 0.06206 seconds
|