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 10:08 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 12:07 |
Dirk Fauth Messages: 2903 Registered: July 2012 |
Senior Member |
|
|
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 06:35 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 #1707790 is a reply to message #1707771] |
Wed, 09 September 2015 11:42 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
Quote:I still don't understand what you are trying to achieve. Is it about the height of the table? Maybe you have another control that takes the other space?
Maybe I see things totally wrong. If you look into the attached file, there is an arrow that shows to a point I can move in order to change the size of the frame. Instead of moving the frame, I would like to set a value for vertical spanning, e.g. 8, such that vertical spanning goes over 8 rows. The problem is that after setting this value, it automatically jumps to 1.
Quote:You need to add the GlazedListsEventLayer on top of the DataLayer of your body layer stack. The FilterRowExampleGridLayer has a DefaultBodyLayerStack which doesn't contain the GlazedListsEventLayer. So basically you need to exchange that with a custom implementation as shown in the other examples.
Which BodyLayerStack should I use instead of the default one?
[Updated on: Wed, 09 September 2015 11:43] Report message to a moderator
|
|
| | | |
Re: Some issues with layout and refresh after list data changed [message #1707906 is a reply to message #1707882] |
Thu, 10 September 2015 11:39 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
Quote:I build my UIs programmatically to avoid such issues. I really don't have a clue what your layout issue could be.
OK, then I think it's the best if you could tell me how you set the vertical spanning in a org.eclipse.swt.layout.GridLayout, please?
Quote:Is there a SortHeaderLayer in your column header layer stack? Do you have a SortedList somewhere? I think the examples should point out to everything.
No and no. I am trying to understand which ingredients I need for multi column sorting by understanding the example "SortableGridExample", but even after some hours I don't see what is really necessary. So the line "this.nattable.addConfiguration(new SingleClickSortConfiguration());" should be one ingredient. Which are the other ones and how do I need to employ them?
EDIT:
Concerning my second question. Now I found this useful sentence "@see GlazedListsGridLayer to see the required stack setup." I'll check it first, so you don't need to answer to the second question.
[Updated on: Thu, 10 September 2015 12:01] Report message to a moderator
|
|
| |
Re: Some issues with layout and refresh after list data changed [message #1708145 is a reply to message #1707908] |
Mon, 14 September 2015 08:46 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 09:52 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 10:03 |
Dirk Fauth Messages: 2903 Registered: July 2012 |
Senior Member |
|
|
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 10:51 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 12:11 |
Dirk Fauth Messages: 2903 Registered: July 2012 |
Senior Member |
|
|
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 08:52 |
Mick Miralas Messages: 16 Registered: July 2015 |
Junior Member |
|
|
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 187 times)
|
|
| | | | | | |
Goto Forum:
Current Time: Thu Sep 26 04:53:15 GMT 2024
Powered by FUDForum. Page generated in 0.06753 seconds
|