Home » Eclipse Projects » NatTable » Some issues with layout and refresh after list data changed
Some issues with layout and refresh after list data changed [message #1707645] |
Tue, 08 September 2015 06:08  |
Eclipse User |
|
|
|
Hello,
I have the following issues and kindly ask for help:
1.) The horizontalSpan is set to 4, but the columns don't fit to the whole space, as you can see in the attached picture "guiFilled.PNG".
2.) The verticalSpan changes its value automatically to -1 after I set it to 4. As you can see in the attached picture "guiDesign.PNG" I can influence the size by clicking and moving the frame, but during runtime, NatTable doesn't use the whole vertical space.
3.) As you can see in the attached picture "guiFilled.PNG" the row count numbers are shortened to 14..., i.e. the column does not grow.
4.) I have a private instance variable "underlyingLayer" of type FilterRowExampleGridLayer. After entering the search parameters and clicking on Search, within the event handler, I am using the following code in order to replace the old list data and providing the list with the new data:
underlyingLayer.getEventList().clear();
unerlyingLayer.getEventList().addAll(searchResultsList);
-Is this a good solution or can this be done more elegantly?
-Problem: NatTable doesn't refresh, i.e. I have to click within the area of NatTable to let it show the new data.
Thank you very much!
Regards,
Mick
|
|
|
Re: Some issues with layout and refresh after list data changed [message #1707657 is a reply to message #1707645] |
Tue, 08 September 2015 08:07   |
Eclipse User |
|
|
|
Quote:1.) The horizontalSpan is set to 4, but the columns don't fit to the whole space, as you can see in the attached picture "guiFilled.PNG".
How do you set the horizontalSpan? Are you using a SpanningDataLayer?
Quote:2.) The verticalSpan changes its value automatically to -1 after I set it to 4. As you can see in the attached picture "guiDesign.PNG" I can influence the size by clicking and moving the frame, but during runtime, NatTable doesn't use the whole vertical space.
Again, how do you set the verticalSpan? I'm not sure if you use the framework for that. It looks like you are overriding some internal methods?
Quote:3.) As you can see in the attached picture "guiFilled.PNG" the row count numbers are shortened to 14..., i.e. the column does not grow.
If you don't configure that it should do that, it won't do that. I assume you are using the DefaultRowHeaderDataLayer which sets a default width of 40 pixels. Either change the default width to something bigger or configure a TextPainter that is configured for automatic size calculation.
Quote:-Is this a good solution or can this be done more elegantly?
That depends on your architecture. But yes, you typically operate on the EventList directly.
Quote:-Problem: NatTable doesn't refresh, i.e. I have to click within the area of NatTable to let it show the new data.
Are you using the GlazedListsEventLayer in your composition? That layer is responsible for listening to list change events and propagate the refresh to NatTable.
|
|
|
Re: Some issues with layout and refresh after list data changed [message #1707752 is a reply to message #1707657] |
Wed, 09 September 2015 02:35   |
Eclipse User |
|
|
|
Quote:How do you set the horizontalSpan? Are you using a SpanningDataLayer?
Again, how do you set the verticalSpan? I'm not sure if you use the framework for that. It looks like you are overriding some internal methods?
Actually, I have adapted the example classes, especially "FilterRowGridExample" and "FilterRowExampleGridLayer" which extends GridLayer. I think I should also mention the following three lines:
GridData gd_natTable = new GridData(SWT.FILL, SWT.FILL, false, false, 4, 1);
gd_natTable.heightHint = 323;
natTable.setLayoutData(gd_natTable);
Quote:If you don't configure that it should do that, it won't do that. I assume you are using the DefaultRowHeaderDataLayer which sets a default width of 40 pixels. Either change the default width to something bigger or configure a TextPainter that is configured for automatic size calculation.
I've tried the first option, but it doesn't show a difference:
// Column header layer
IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
columnHeaderDataLayer.setDefaultColumnWidth(100);
Quote:Are you using the GlazedListsEventLayer in your composition? That layer is responsible for listening to list change events and propagate the refresh to NatTable.
No. In relation to the example classes: How/Where do I have to set that?
|
|
| | | | | | | | | |
Re: Some issues with layout and refresh after list data changed [message #1708145 is a reply to message #1707908] |
Mon, 14 September 2015 04:46   |
Eclipse User |
|
|
|
Unfortunately, I don't know how to successfully finish the implementation of sorting, since I am faced with more and more issues. My problem now is that GlazedlistsColumnHeader constructor receives a DefaultBodyLayerStack, but I have implemented a custom BodyLayerStack. Any help would be much appreciated (maybe it's simple, but I am in the end phase of the thesis and therefore probably blind):
/*******************************************************************************
* Copyright (c) 2012, 2013 Original authors 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:
* Original authors and others - initial API and implementation
******************************************************************************/
package anwendungsservertest.view;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
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.filterrow.DefaultGlazedListsFilterStrategy;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
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.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import anwendungsservertest.serverklassen.Part2;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
/**
* Factory for assembling GridLayer and the child layers - with support for
* GlazedLists and sorting
*
* @see {@linkplain http://publicobject.com/glazedlists/}
*/
public class GlazedListsGridLayer<T> extends GridLayer {
private ListDataProvider<T> bodyDataProvider;
private EventList eventList;
private TransformedList rowObjectsGlazedList;
private GlazedListsColumnHeaderLayerStack<T> columnHeaderLayerStack;
private DataLayer bodyDataLayer;
private BodyLayerStack bodyLayerStack;
private ColumnOverrideLabelAccumulator bodyLabelAccumulator;
public GlazedListsGridLayer(IConfigRegistry configRegistry) {
super(true);
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
FilterList filterList = new FilterList(this.eventList);
this.rowObjectsGlazedList = GlazedLists.threadSafeList(filterList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
/*bodyLabelAccumulator.registerColumnOverrides(RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
"PRICING_TYPE_PROP_NAME");*/
// Body - with list event listener
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
this.bodyDataProvider = new ListDataProvider<T>(sortedList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
// Column header layer
IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayerStack, bodyLayerStack.getSelectionLayer());
SortHeaderLayer<T> sortHeaderLayer = new SortHeaderLayer<T>(columnHeaderLayer, new GlazedListsSortModel<T>(sortedList, columnPropertyAccessor,
configRegistry, columnHeaderDataLayer), false);
this.columnHeaderLayerStack = new GlazedListsColumnHeaderLayerStack<T>(columnHeaderDataProvider, sortedList, columnPropertyAccessor,
configRegistry, this.bodyLayerStack);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<T> filterRowHeaderLayer = new FilterRowHeaderComposite<T>(
new DefaultGlazedListsFilterStrategy<T>(filterList, columnPropertyAccessor, configRegistry),
sortHeaderLayer, columnHeaderDataProvider, configRegistry);
// Row header
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, this.bodyLayerStack, this.bodyLayerStack.getSelectionLayer());
// Corner
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(this.columnHeaderLayerStack.getDataProvider(), rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, this.columnHeaderLayerStack);
// Grid
setBodyLayer(this.bodyLayerStack);
setColumnHeaderLayer(this.columnHeaderLayerStack);
setRowHeaderLayer(rowHeaderLayer);
setCornerLayer(cornerLayer);
}
public ColumnOverrideLabelAccumulator getColumnLabelAccumulator() {
return bodyLabelAccumulator;
}
@Override
public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
super.setClientAreaProvider(clientAreaProvider);
}
public DataLayer getBodyDataLayer() {
return this.bodyDataLayer;
}
public ListDataProvider<T> getBodyDataProvider() {
return this.bodyDataProvider;
}
public GlazedListsColumnHeaderLayerStack<T> getColumnHeaderLayerStack() {
return this.columnHeaderLayerStack;
}
public BodyLayerStack getBodyLayerStack() {
return this.bodyLayerStack;
}
public EventList getEventList(){
eturn eventList;
}
/**
* Always encapsulate the body layer stack in an AbstractLayerTransform to
* ensure that the index transformations are performed in later commands.
*
* @param <T>
*/
class BodyLayerStack<T> extends AbstractLayerTransform {
private final SelectionLayer selectionLayer;
public BodyLayerStack(GlazedListsEventLayer<T> glazedListsEventLayer) {
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
}
|
|
| |
Re: Some issues with layout and refresh after list data changed [message #1708152 is a reply to message #1708146] |
Mon, 14 September 2015 05:52   |
Eclipse User |
|
|
|
Quote:And if you want to stick with the GlazedListsColumnHeaderLayerStack, copy it into your project and modify it to fit your needs.
Due to time pressure I sticked with the GlazedListsColumnHeaderLayerStack and modified it.
Quote:You should also be careful with the layer stack creation. AFAIKS you are creating a body layer stack twice, which will lead to reference issues later on.
At which place does this happen?
My new code is the following one, but I get errors (please see attached file):
/*******************************************************************************
* Copyright (c) 2012, 2013 Original authors 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:
* Original authors and others - initial API and implementation
******************************************************************************/
package anwendungsservertest.view;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.DefaultGlazedListsFilterStrategy;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
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.CornerLayer;
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.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
/**
* Factory for assembling GridLayer and the child layers - with support for
* GlazedLists and sorting
*
* @see {@linkplain http://publicobject.com/glazedlists/}
*/
public class GlazedListsGridLayer<T> extends GridLayer {
private ListDataProvider<T> bodyDataProvider;
private EventList eventList;
private TransformedList rowObjectsGlazedList;
private GlazedListsColumnHeaderLayerStack<T> columnHeaderLayerStack;
private DataLayer bodyDataLayer;
private BodyLayerStack bodyLayerStack;
private ColumnOverrideLabelAccumulator bodyLabelAccumulator;
private IDataProvider columnHeaderDataProvider;
public GlazedListsGridLayer(IConfigRegistry configRegistry) {
super(true);
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
FilterList filterList = new FilterList(this.eventList);
this.rowObjectsGlazedList = GlazedLists.threadSafeList(filterList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
/*bodyLabelAccumulator.registerColumnOverrides(RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
"PRICING_TYPE_PROP_NAME");*/
// Body - with list event listener
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
this.bodyDataProvider = new ListDataProvider<T>(sortedList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
// Column header layer
this.columnHeaderLayerStack = new GlazedListsColumnHeaderLayerStack<T>(columnHeaderDataProvider, sortedList, columnPropertyAccessor,
configRegistry, this.bodyLayerStack);
this.columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<T> filterRowHeaderLayer = new FilterRowHeaderComposite<T>(
new DefaultGlazedListsFilterStrategy<T>(filterList, columnPropertyAccessor, configRegistry),
this.columnHeaderLayerStack.getColumnHeaderLayer(), columnHeaderDataProvider, configRegistry);
// Row header
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, this.bodyLayerStack, this.bodyLayerStack.getSelectionLayer());
// Corner
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(this.columnHeaderLayerStack.getDataProvider(), rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, this.columnHeaderLayerStack);
// Grid
setBodyLayer(this.bodyLayerStack);
setColumnHeaderLayer(this.columnHeaderLayerStack);
setRowHeaderLayer(rowHeaderLayer);
setCornerLayer(cornerLayer);
}
public ColumnOverrideLabelAccumulator getColumnLabelAccumulator() {
return bodyLabelAccumulator;
}
@Override
public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
super.setClientAreaProvider(clientAreaProvider);
}
public DataLayer getBodyDataLayer() {
return this.bodyDataLayer;
}
public ListDataProvider<T> getBodyDataProvider() {
return this.bodyDataProvider;
}
public GlazedListsColumnHeaderLayerStack<T> getColumnHeaderLayerStack() {
return this.columnHeaderLayerStack;
}
public BodyLayerStack getBodyLayerStack() {
return this.bodyLayerStack;
}
public EventList getEventList(){
return eventList;
}
/**
* Always encapsulate the body layer stack in an AbstractLayerTransform to
* ensure that the index transformations are performed in later commands.
*
* @param <T>
*/
class BodyLayerStack<T> extends AbstractLayerTransform {
private final SelectionLayer selectionLayer;
public BodyLayerStack(GlazedListsEventLayer<T> glazedListsEventLayer) {
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
}
|
|
|
Re: Some issues with layout and refresh after list data changed [message #1708159 is a reply to message #1708152] |
Mon, 14 September 2015 06:03   |
Eclipse User |
|
|
|
Change
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
FilterList filterList = new FilterList(this.eventList);
this.rowObjectsGlazedList = GlazedLists.threadSafeList(filterList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
/*bodyLabelAccumulator.registerColumnOverrides(RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
"PRICING_TYPE_PROP_NAME");*/
// Body - with list event listener
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
this.bodyDataProvider = new ListDataProvider<T>(sortedList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
To a correct stack like:
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
this.rowObjectsGlazedList = GlazedLists.threadSafeList(eventList );
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
FilterList filterList = new FilterList(sortedList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
and create the bodyDataLayer and the bodyDataProvider only once.
Maybe you should try to understand things instead of copy & paste code together from multiple sources you don't understand.
BTW, this is the same way it is shown in the integration examples of the Tutorials section. So if you would have copied the correct sources and not the examples I told you to not look at, you would not have these issues.
|
|
|
Re: Some issues with layout and refresh after list data changed [message #1708169 is a reply to message #1708159] |
Mon, 14 September 2015 06:51   |
Eclipse User |
|
|
|
Quote:BTW, this is the same way it is shown in the integration examples of the Tutorials section. So if you would have copied the correct sources and not the examples I told you to not look at, you would not have these issues.
Mea culpa. I underestimated the complexity.
Thank you for your help and sorry to be the bringer of bad news, but after chaning my code accoridng to you last post, I still get errors (please see file attached). The new code is as follows:
/*******************************************************************************
* Copyright (c) 2012, 2013 Original authors 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:
* Original authors and others - initial API and implementation
******************************************************************************/
package anwendungsservertest.view;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.DefaultGlazedListsFilterStrategy;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
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.CornerLayer;
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.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
/**
* Factory for assembling GridLayer and the child layers - with support for
* GlazedLists and sorting
*
* @see {@linkplain http://publicobject.com/glazedlists/}
*/
public class GlazedListsGridLayer<T> extends GridLayer {
private ListDataProvider<T> bodyDataProvider;
private EventList eventList;
private TransformedList rowObjectsGlazedList;
private GlazedListsColumnHeaderLayerStack<T> columnHeaderLayerStack;
private DataLayer bodyDataLayer;
private BodyLayerStack bodyLayerStack;
private ColumnOverrideLabelAccumulator bodyLabelAccumulator;
private IDataProvider columnHeaderDataProvider;
public GlazedListsGridLayer(IConfigRegistry configRegistry) {
super(true);
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
this.rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
FilterList filterList = new FilterList(sortedList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
/*bodyLabelAccumulator.registerColumnOverrides(RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
"PRICING_TYPE_PROP_NAME");*/
// Column header layer
this.columnHeaderLayerStack = new GlazedListsColumnHeaderLayerStack<T>(columnHeaderDataProvider, sortedList, columnPropertyAccessor,
configRegistry, this.bodyLayerStack);
this.columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<T> filterRowHeaderLayer = new FilterRowHeaderComposite<T>(
new DefaultGlazedListsFilterStrategy<T>(filterList, columnPropertyAccessor, configRegistry),
this.columnHeaderLayerStack.getColumnHeaderLayer(), columnHeaderDataProvider, configRegistry);
// Row header
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, this.bodyLayerStack, this.bodyLayerStack.getSelectionLayer());
// Corner
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(this.columnHeaderLayerStack.getDataProvider(), rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, this.columnHeaderLayerStack);
// Grid
setBodyLayer(this.bodyLayerStack);
setColumnHeaderLayer(this.columnHeaderLayerStack);
setRowHeaderLayer(rowHeaderLayer);
setCornerLayer(cornerLayer);
}
public ColumnOverrideLabelAccumulator getColumnLabelAccumulator() {
return bodyLabelAccumulator;
}
@Override
public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
super.setClientAreaProvider(clientAreaProvider);
}
public DataLayer getBodyDataLayer() {
return this.bodyDataLayer;
}
public ListDataProvider<T> getBodyDataProvider() {
return this.bodyDataProvider;
}
public GlazedListsColumnHeaderLayerStack<T> getColumnHeaderLayerStack() {
return this.columnHeaderLayerStack;
}
public BodyLayerStack getBodyLayerStack() {
return this.bodyLayerStack;
}
public EventList getEventList(){
return eventList;
}
/**
* Always encapsulate the body layer stack in an AbstractLayerTransform to
* ensure that the index transformations are performed in later commands.
*
* @param <T>
*/
class BodyLayerStack<T> extends AbstractLayerTransform {
private final SelectionLayer selectionLayer;
public BodyLayerStack(GlazedListsEventLayer<T> glazedListsEventLayer) {
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
}
|
|
|
Re: Some issues with layout and refresh after list data changed [message #1708181 is a reply to message #1708169] |
Mon, 14 September 2015 08:11   |
Eclipse User |
|
|
|
It is a NullPointerException. And it looks like it is because of your copy & paste operations. And you expect me to solve your problems that exist because you simply copied stuff without understanding. It is really annoying!
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
Why do you use the RowDataListFixture from our examples or test data? I assume you didn't wrote your own and therefore it returns the wrong values.
And what is this?
this.columnHeaderLayerStack = new GlazedListsColumnHeaderLayerStack<T>(columnHeaderDataProvider, sortedList, columnPropertyAccessor, configRegistry, this.bodyLayerStack);
this.columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
You are creating the column header layer stack with a not initialized columnHeaderDataProvider and expect everything works fine when you create it afterwards? A reference to null will never update to another reference if you specify the reference afterwards.
But a debugger would have told you the same!
|
|
| |
Re: Some issues with layout and refresh after list data changed [message #1708394 is a reply to message #1708287] |
Wed, 16 September 2015 04:52   |
Eclipse User |
|
|
|
Hello Dirk,
unfortunately I need your help again.
While documenting the NatTable prototype, I noticed that when I want to filter the data and therefore click into the correspondent area (please see file attached), I can not type anything into it and clicking elsewhere in the table is no more possible.
Do you have any idea what's the reason for this?
/*******************************************************************************
* Copyright (c) 2012, 2013 Original authors 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:
* Original authors and others - initial API and implementation
******************************************************************************/
package anwendungsservertest.view;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.data.ReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.DefaultGlazedListsFilterStrategy;
import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
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.CornerLayer;
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.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.util.IClientAreaProvider;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.SortedList;
import ca.odell.glazedlists.TransformedList;
/**
* Factory for assembling GridLayer and the child layers - with support for
* GlazedLists and sorting
*
* @see {@linkplain http://publicobject.com/glazedlists/}
*/
public class GlazedListsGridLayer<T> extends GridLayer {
private ListDataProvider<T> bodyDataProvider;
private EventList eventList;
private TransformedList rowObjectsGlazedList;
private GlazedListsColumnHeaderLayerStack<T> columnHeaderLayerStack;
private DataLayer bodyDataLayer;
private BodyLayerStack bodyLayerStack;
private ColumnOverrideLabelAccumulator bodyLabelAccumulator;
private IDataProvider columnHeaderDataProvider;
public GlazedListsGridLayer(IConfigRegistry configRegistry) {
super(true);
// Underlying data source
this.eventList = GlazedLists.eventList(new ArrayList<T>());
this.rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
// NOTE: Remember to use the SortedList constructor with 'null' for the Comparator
SortedList<T> sortedList = new SortedList<T>(rowObjectsGlazedList, null);
FilterList filterList = new FilterList(sortedList);
String[] propertyNames = {"prtno", "nomcl", "inidt", "prtky", "testts", "remark", "testdf", "testti"};
Map<String, String> propertyToLabelMap = RowDataListFixture.getPropertyToLabelMap();
// Body layer
IColumnPropertyAccessor<T> columnPropertyAccessor = new ReflectiveColumnPropertyAccessor<T>(propertyNames);
this.bodyDataProvider = new ListDataProvider<T>(filterList, columnPropertyAccessor);
this.bodyDataLayer = new DataLayer(this.bodyDataProvider);
bodyDataLayer.setColumnPercentageSizing(true);
// layer for event handling of GlazedLists and PropertyChanges
GlazedListsEventLayer<T> glazedListsEventLayer = new GlazedListsEventLayer<T>(this.bodyDataLayer, filterList);
this.bodyLayerStack = new BodyLayerStack(glazedListsEventLayer);
this.bodyLabelAccumulator = new ColumnOverrideLabelAccumulator(bodyDataLayer);
bodyDataLayer.setConfigLabelAccumulator(bodyLabelAccumulator);
/*bodyLabelAccumulator.registerColumnOverrides(RowDataListFixture.getColumnIndexOfProperty(RowDataListFixture.PRICING_TYPE_PROP_NAME),
"PRICING_TYPE_PROP_NAME");*/
// Column header layer
this.columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
this.columnHeaderLayerStack = new GlazedListsColumnHeaderLayerStack<T>(columnHeaderDataProvider, sortedList, columnPropertyAccessor,
configRegistry, this.bodyLayerStack);
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<T> filterRowHeaderLayer = new FilterRowHeaderComposite<T>(
new DefaultGlazedListsFilterStrategy<T>(filterList, columnPropertyAccessor, configRegistry),
this.columnHeaderLayerStack.getColumnHeaderLayer(), columnHeaderDataProvider, configRegistry);
filterRowHeaderLayer.setChildLayer(GridRegion.COLUMN_HEADER, this.columnHeaderLayerStack, 0, 0);
// Row header
DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(this.bodyDataProvider);
DefaultRowHeaderDataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, this.bodyLayerStack, this.bodyLayerStack.getSelectionLayer());
// Corner
DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(this.columnHeaderLayerStack.getDataProvider(), rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, this.columnHeaderLayerStack);
// Grid
setBodyLayer(this.bodyLayerStack);
setColumnHeaderLayer(filterRowHeaderLayer);
setRowHeaderLayer(rowHeaderLayer);
setCornerLayer(cornerLayer);
}
public ColumnOverrideLabelAccumulator getColumnLabelAccumulator() {
return bodyLabelAccumulator;
}
@Override
public void setClientAreaProvider(IClientAreaProvider clientAreaProvider) {
super.setClientAreaProvider(clientAreaProvider);
}
public DataLayer getBodyDataLayer() {
return this.bodyDataLayer;
}
public ListDataProvider<T> getBodyDataProvider() {
return this.bodyDataProvider;
}
public GlazedListsColumnHeaderLayerStack<T> getColumnHeaderLayerStack() {
return this.columnHeaderLayerStack;
}
public BodyLayerStack getBodyLayerStack() {
return this.bodyLayerStack;
}
public EventList getEventList(){
return eventList;
}
/**
* Always encapsulate the body layer stack in an AbstractLayerTransform to
* ensure that the index transformations are performed in later commands.
*
* @param <T>
*/
class BodyLayerStack<T> extends AbstractLayerTransform {
private final SelectionLayer selectionLayer;
public BodyLayerStack(GlazedListsEventLayer<T> glazedListsEventLayer) {
this.selectionLayer = new SelectionLayer(glazedListsEventLayer);
ViewportLayer viewportLayer = new ViewportLayer(getSelectionLayer());
setUnderlyingLayer(viewportLayer);
}
public SelectionLayer getSelectionLayer() {
return this.selectionLayer;
}
}
}
Attachment: freeze.PNG
(Size: 43.82KB, Downloaded 212 times)
|
|
| | | | | |
Re: Some issues with layout and refresh after list data changed [message #1708650 is a reply to message #1708636] |
Fri, 18 September 2015 08:00  |
Eclipse User |
|
|
|
Now it (really) works!
I had a look into FullFeaturedColumnHeaderLayerStack.java and got the necessary "inspiration". Honestly, I don't know what exactly was responsible for the issues, but i moved the instantiation of filterRowHeaderComposite to my adapted class GlazedListsColumnHeaderLayerStack, plus changed the argument of setUnderlyingLayer to filterRowHeaderLayer and now it works.
So thanks again for the great and quick support. Now I solely have to finish the documentation of the NatTable prototype. The result of my work is a recommendation for RCP, since there is a lot of open source stuff for it. If you look at C#/WPF, the native possibilities are limited and you have to pay a lot of money, for example if you want a more sophisticated table widget. Additionally, RCP can be seen as platform independent and it should be fit for the future. Whereas a .NET solution based on WPF leads to a dependence on Windows (yes, there are some projects out there that focus on transformation of C#/WPF to HTML5/JavaScript) and Microsoft could stop the support of WPF in a few years.
|
|
|
Goto Forum:
Current Time: Mon Jun 23 05:16:57 EDT 2025
Powered by FUDForum. Page generated in 0.10449 seconds
|