Skip to main content



      Home
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 Go to next message
Eclipse UserFriend
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 #1855893 is a reply to message #1855887] Wed, 09 November 2022 00:08 Go to previous messageGo to next message
Eclipse UserFriend
As far as I can see you are talking about the row header that is not updating, not the row group header. And the default row header is updating automatically as it has a dimensional dependency to the body layer stack. But it seems you are not using the default row header data provider, as you are showing an information that is extracted out of the data model you are using.

Since you don't provide information about your row header data provider, I can't help. Only thing I can assume is that you are operating on the base list item for retrieving the information you show in the row header, where you should use the top most collection that is used in the body layer, typically the FilterList.
Re: How to update row group header while filtering [message #1855903 is a reply to message #1855893] Wed, 09 November 2022 04:51 Go to previous messageGo to next message
Eclipse UserFriend
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 #1855909 is a reply to message #1855903] Wed, 09 November 2022 07:33 Go to previous messageGo to next message
Eclipse UserFriend
Your SimpleRowHeaderDataProvider is simply operating on a static list. How should that correlate to the body layer if the information is not retrieved from the body? Instead of passing "finalRows" which seems to be the pre-collected collection of values you want to show in the row header, you should pass the reference to the body data provider to retrieve the data to show on demand.
Re: How to update row group header while filtering [message #1855922 is a reply to message #1855909] Wed, 09 November 2022 16:57 Go to previous messageGo to next message
Eclipse UserFriend
Yes. "finalRows" are list of row header strings. But how can i configure the dynamic filtered list of row headers to the body data provider.

I have seen nattable GlazedListsFilterExample with DefaultRowHeaderDataProvider. After filtering, the default row numbers are starting from "1"only instead of actual row index from base list.
Same scenario for me, but it is row headers instead of default row numbers.

I tried to retrieve object from filter list and tried to retrieve that object index from base list. As i have multiple similar objects in base list, always i am getting the first index of that object instead of actual one.

Do you think any solution for this?

Thank you in Advance
Re: How to update row group header while filtering [message #1855927 is a reply to message #1855922] Thu, 10 November 2022 00:37 Go to previous messageGo to next message
Eclipse UserFriend
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();
                    }
                };
Re: How to update row group header while filtering [message #1855946 is a reply to message #1855927] Thu, 10 November 2022 12:00 Go to previous message
Eclipse UserFriend
Hi Dirk,

Thank you for your explanation. As you suggested i created getId() method for row object and changed my rowHeaderDataProvider. Now its working fine as expected.
Thanks a lot for your support.
Previous Topic:Fill down function
Next Topic:Vertical scroll bar is appearing when filter applied wrt base list with empty rows
Goto Forum:
  


Current Time: Sat May 24 07:14:10 EDT 2025

Powered by FUDForum. Page generated in 0.06206 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top