Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » Misbehaving two-level column groups
Misbehaving two-level column groups [message #1240036] Wed, 05 February 2014 15:22 Go to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Hello all,

I need to create a somewhat complex configuration with NatTable. The aim is to achieve an excel-like behavior and look. Tree structure and multiple levels of column groups are also involved.

I have a problem with the multi-level column grouping. I followed the _001_Two_level_column_groups example to implement it, but this example also has the problem i encountered.

Here is a picture of how my NatTable currently looks like:
http://s30.postimg.org/84nginjpt/natttable.png

The topmost row with the colored groups is achieved with a ColumnGroupGroupHeaderLayer.

The "CAPEX FC *" groups are currently collapsed with the static "Total" column visible, achieved with ColumnGroupHeaderLayer.

The rest of the columns are grouped directly under the ColumnGroupGroupHeaderLayer.

My problem is that at the colored top-groups i'm not able to set the static columns (no method in "GroupGroup" layer), and collapsing/expanding does not work either. If i double click on a colored top group, it throws an exception like:

java.lang.NullPointerException
	at org.eclipse.nebula.widgets.nattable.group.command.ColumnGroupExpandCollapseCommandHandler.doCommand(ColumnGroupExpandCollapseCommandHandler.java:47)
	at org.eclipse.nebula.widgets.nattable.group.command.ColumnGroupExpandCollapseCommandHandler.doCommand(ColumnGroupExpandCollapseCommandHandler.java:1)


and instead of collapsing/expanding the group, it triggers a sorting command on the column "below" the event location.

I can only expand/collapse the sub-groups defined in the ColumnGroupHeaderLayer.

Is this the expected behavior?

I found a related bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=379940

Does this mean that multiple level column grouping is not fully supported? After digging into the sources and examining the exception above, to me it looks like it's not. If it is however, what am i doing wring?

I would post my code but i'm using a custom way to initialize the column groups from a hierarchical model, but in theory it works exactly like the _001_Two_level_column_groups example.
Re: Misbehaving two-level column groups [message #1240046 is a reply to message #1240036] Wed, 05 February 2014 15:38 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Hi,

the multi-level column grouping is something that didn't got much love in the past. AFAIK it has several issues and IMHO it needs to be redesigned completely. For example, having new layers for each grouping level doesn't feel like a good design to me. The bug you found is saying this. It needs to be redesigned.

Quote:
Does this mean that multiple level column grouping is not fully supported? After digging into the sources and examining the exception above, to me it looks like it's not. If it is however, what am i doing wring?


It is supported up to two level (columnGroup and columnGroupGroup) but it has some issues AFAIK.

What makes me wonder a bit is this
Quote:
The rest of the columns are grouped directly under the ColumnGroupGroupHeaderLayer.


I'm not sure what you mean with this.

Looking into the example, expand/collapse is working with the columnGroupGroup. Or how did you reproduce the issue exactly?

Without seeing code, or knowing how to reproduce, I'm not sure how to help.

Greez,
Dirk
Re: Misbehaving two-level column groups [message #1240314 is a reply to message #1240046] Thu, 06 February 2014 07:36 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Hello Dirk,

first of all, thanks for your quick reply. The issues i'm having with _001_Two_level_column_groups:

1.) if you place the mouse pointer on "GroupGroup 1" but horizontally above the "rating" column and double click, "Group 1" gets closed instead of "GroupGroup 1"
2.) if you then double click again on the exact same location, an exception is thrown and the example freezes completely
3.) if you double click on "GroupGroup 1" having the mouse pointer above "UnBreakable group 2", it closes that group again instead of "GroupGroup 1"
4.) if you double click on "GroupGroup 1" having the mouse pointer above "Issue Date", an exception is thrown and the example freezes completely

My need is to be able to configure the "GroupGroup" layer in such a way that if one double clicks on "GroupGroup 1" only the "Issue Date" column (or only group 1, 2, etc...) remains visible, like it is possible with ColumnGroupHeaderLayer.

About this: "The rest of the columns are grouped directly under the ColumnGroupGroupHeaderLayer."

If you look at "UnBreakable group 3" in the example, it's columns are added to the ColumnGroupHeaderLayer. This way the group header takes place in the upper two rows in a merged cell, and expanding/collapsing the group works properly. Unfortunately i need a different visual outcome, having the group header only taking the uppermost row and the column headers spanning vertically two rows. While i could achieve this by adding the column indices to the ColumnGroupGroupHeaderLayer instead of the ColumnGroupHeaderLayer, collapsing/expanding no longer works, if i double click on the group header, an exception is thrown and sorting happens on the column below the event's location.
Re: Misbehaving two-level column groups [message #1240336 is a reply to message #1240314] Thu, 06 February 2014 08:53 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Ok, I can reproduce that.

As I said before, the multi level column grouping didn't get much love in the past.

The issues seem to be related to wrong action bindings. It looks like the expand/collapse action is executed on the columngroup layer instead of the columngroupgroup layer. Not sure if only a binding is missing or the existing binding is wrong. But that's the place I would start searching for a solution.

Feel free to open a ticket and insert your investigations so far. It would also be great if you could take care of that and contribute a solution. Smile
Re: Misbehaving two-level column groups [message #1240343 is a reply to message #1240336] Thu, 06 February 2014 09:05 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Thanks, i will look into the bindings to see what's happening.
Re: Misbehaving two-level column groups [message #1240419 is a reply to message #1240343] Thu, 06 February 2014 12:08 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Here is what i've found:

- both ColumnGroupHeaderLayer and ColumnGroupGroupHeaderLayer register the same ColumnGroupExpandCollapseAction for double clicking through DefaultColumnGroupHeaderLayerConfiguration
- the above action issues a ColumnGroupExpandCollapseCommand which only carries the column position where the event occurred
- the command is handled by ColumnGroupExpandCollapseCommandHandler which is registered by the ColumnGroupExpandCollapseLayer

this is where the problem starts show up:

- the ColumnGroupExpandCollapseLayer is working with the ColumnGroupModel associated with ColumnGroupHeaderLayer, and because the ColumnGroupExpandCollapseCommandHandler relies on the layer that registers it, it also uses the same ColumnGroupModel

Possible solution:

- supply all ColumnGroupModels to the ColumnGroupExpandCollapseLayer
- extend the command to also carry the information on which level the event was detected
- the correct ColumnGroupModel to use can be selected using the commands level parameter

what do you think?
Re: Misbehaving two-level column groups [message #1240429 is a reply to message #1240419] Thu, 06 February 2014 12:36 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Sounds like an idea. Of course you will need to adjust the ColumnGroupExpandCollapseLayer to take all ColumnGroupModels into account the right way. Internally it is just an AbstractColumnHideShowLayer that calculates the hidden columns out of the column group model state.

If you are able to manage that in a generic way so multiple ColumnGroupModels can be used, the first big step in adding support for >2 column group levels might be done.
Re: Misbehaving two-level column groups [message #1265478 is a reply to message #1240429] Thu, 06 March 2014 06:29 Go to previous messageGo to next message
neal zhang is currently offline neal zhangFriend
Messages: 45
Registered: July 2012
Member
Hi all,
How about this problem? i also use nattable and need to fix it.
Re: Misbehaving two-level column groups [message #1265531 is a reply to message #1265478] Thu, 06 March 2014 08:10 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
neal zhang wrote on Thu, 06 March 2014 01:29
Hi all,
How about this problem? i also use nattable and need to fix it.


I have not went into the problem yet, unfortunately i have bigger priorities with my project. But soon i will have to solve this, then i'll post about it asap.
Re: Misbehaving two-level column groups [message #1268170 is a reply to message #1265531] Mon, 10 March 2014 06:29 Go to previous messageGo to next message
neal zhang is currently offline neal zhangFriend
Messages: 45
Registered: July 2012
Member
Hi Istvan,
Thank you for your reply,i have urgent task for it,so i will try to do it first.
Re: Misbehaving two-level column groups [message #1272200 is a reply to message #1268170] Mon, 17 March 2014 10:29 Go to previous messageGo to next message
neal zhang is currently offline neal zhangFriend
Messages: 45
Registered: July 2012
Member
implement nattable for n levels of column groups and expand/collapse of columngroup,write steps,and i hope can help others,but it is temp way,i believe dirk will implement it in source codes.

extends some classes.
xxx extends ColumnGroupExpandCollapseAction -- get row position to columnCommand.
xxx extends AbstractColumnCommand --get row position.
xxx extends AbstractLayerCommandHandler --get ColumnGroupModel by row position.
xxx extends ColumnGroupExpandCollapseLayer --create ColumnGroupModel[] models;
ColumnGroupGroupHeaderLayerEx extends AbstractLayerTransform -- have a constructor which use ColumnGroupGroupHeaderLayerEx as a parameter.
xxx extends DefaultColumnGroupHeaderLayerConfiguration
uiBindingRegistry.unregisterDoubleClickBinding((MouseEventMatcher.columnGroupHeaderLeftClick(SWT.NONE)));
uiBindingRegistry.registerDoubleClickBinding(MouseEventMatcher.columnGroupHeaderLeftClick(SWT.NONE),
new ColumnGroupExpandCollapseActionEx());

ColumnGroupModelEx extends ColumnGroupModel -- have a field "ColumnGroupModelEx child"

Re: Misbehaving two-level column groups [message #1273614 is a reply to message #1272200] Thu, 20 March 2014 09:05 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Hi,

thanks for the investigation and the solution proposal. With some modifications and extensions I added that to NatTable core. I still think the whole column grouping concept in NatTable needs to be reworked. But for the moment the issues should be solved.

So I got rid of the NPE, made expand/collapse work and added API to set static columns (although this could be done via ColumnGroupModel before, as the method is just delegates to the model).

https://bugs.eclipse.org/bugs/show_bug.cgi?id=429610
https://bugs.eclipse.org/bugs/show_bug.cgi?id=430768

Could you please verify if the modifications are solving your issues? As I just pushed it to the repository, SNAPSHOTS >= 281 should contain the modifications.

Greez,
Dirk
Re: Misbehaving two-level column groups [message #1278930 is a reply to message #1273614] Fri, 28 March 2014 02:45 Go to previous messageGo to next message
neal zhang is currently offline neal zhangFriend
Messages: 45
Registered: July 2012
Member
Hi Dirk,
Thank you fixed this problem so quickly,and sorry reply late,recently very busy.
by the way,where i can download latest nattable? (you said "As I just pushed it to the repository, SNAPSHOTS >= 281 should contain the modifications.")
i can't find in "http://www.eclipse.org/nattable/download.php",sorry,maybe i am foolish, Mad ,
Re: Misbehaving two-level column groups [message #1279063 is a reply to message #1278930] Fri, 28 March 2014 07:34 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Hi,

you can find the links to the SNAPSHOT builds on the website you linked. See section "Development Snapshot Builds". Wink

http://download.eclipse.org/nattable/snapshots/

Greez,
Dirk
Re: Misbehaving two-level column groups [message #1281125 is a reply to message #1240036] Mon, 31 March 2014 11:49 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Thank you very much for the solution, it works well!
Re: Misbehaving two-level column groups [message #1281220 is a reply to message #1273614] Mon, 31 March 2014 14:48 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
I still found a little flaw in ColumnGroupGroupHeaderLayer.

If you look at the screenshot in my first post, there is a pink GroupGroup (Total Project View). It is configured that if it is collapsed, the "FC (PSP)" column disappears, but all the others remain visible. When the viewport is scrolled to the right, and columns of the group starts the scroll off the visible area on the left, the pink header remains 7 cell width, and therefore intersects with the yellow group.

This can be easily worked out by changing ColumnGroupGroupHeaderLayer#getColumnSpan(int columnPosition) to do not concern whether the group is closed or not:


	protected int getColumnSpan(int columnPosition) {
		int columnIndex = getColumnIndexByPosition(columnPosition);
		ColumnGroup columnGroup = model.getColumnGroupByIndex(columnIndex);

		//if (columnGroup.isCollapsed()) {
		//	int sizeOfStaticColumns = columnGroup.getStaticColumnIndexes().size();
		//	return sizeOfStaticColumns == 0 ? 1 : sizeOfStaticColumns;
		//} else {
			int startPositionOfGroup = getStartPositionOfGroup(columnPosition);
			int sizeOfGroup = columnGroup.getSize();
			int endPositionOfGroup = startPositionOfGroup + sizeOfGroup;
			List<Integer> columnIndexesInGroup = columnGroup.getMembers();

			for (int i = startPositionOfGroup; i < endPositionOfGroup; i++) {
				int index = getColumnIndexByPosition(i);
				if (!columnIndexesInGroup.contains(Integer.valueOf(index))) {
					sizeOfGroup--;
				}
			}
			return sizeOfGroup;
		//}
	}



I assume the "true" branch of that "if" was meant to be a faster short cut to the "false" branch, but somehow does not work properly. I do not fully understand what's happening here, but noticed that if the group is expanded, the glitch does not come up.
Re: Misbehaving two-level column groups [message #1281335 is a reply to message #1281220] Mon, 31 March 2014 18:40 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Quote:
I assume the "true" branch of that "if" was meant to be a faster short cut to the "false" branch


No, it is the case when the group is collapsed but no static columns are configured. Otherwise the group would vanish. At least that is the purpose.

Quote:
It is configured that if it is collapsed, the "FC (PSP)" column disappears, but all the others remain visible


Did you use the static columns to achieve that or did you do this in another way?

There is a related ticket that reports the same: https://bugs.eclipse.org/bugs/show_bug.cgi?id=402007

I tried to reproduce the issue with the existing examples, but everything I tried worked fine.
Re: Misbehaving two-level column groups [message #1281380 is a reply to message #1281335] Mon, 31 March 2014 20:11 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
I really tried to reproduce the issue by creating an example that has two level column grouping, sorting and filtering combined. As the issue occurs in the column header region, I don't think the tree has impact on that.

Maybe your layer composition is not correct. Could you try to reproduce the issue with the following code? And compare your code with that example? Maybe you just need to switch the layer order to avoid the issue.

public class _807_SortableFilterableColumnGroupExample extends AbstractNatExample {

	private final ColumnGroupModel columnGroupModel = new ColumnGroupModel();
	private final ColumnGroupModel sndColumnGroupModel = new ColumnGroupModel();
	
	public static void main(String[] args) throws Exception {
		StandaloneNatExampleRunner.run(600, 400, new _807_SortableFilterableColumnGroupExample());
	}

	@Override
	public Control createExampleControl(Composite parent) {
		//create a new ConfigRegistry which will be needed for GlazedLists handling
		ConfigRegistry configRegistry = new ConfigRegistry();

		//property names of the Person class
		String[] propertyNames = {"firstName", "lastName", "gender", "married", 
				"address.street", "address.housenumber", "address.postalCode", "address.city", 
				"age", "birthday", "money",
				"description", "favouriteFood", "favouriteDrinks"};

		//mapping from property to label, needed for column header labels
		Map<String, String> propertyToLabelMap = new HashMap<String, String>();
		propertyToLabelMap.put("firstName", "Firstname");
		propertyToLabelMap.put("lastName", "Lastname");
		propertyToLabelMap.put("gender", "Gender");
		propertyToLabelMap.put("married", "Married");
		propertyToLabelMap.put("address.street", "Street");
		propertyToLabelMap.put("address.housenumber", "Housenumber");
		propertyToLabelMap.put("address.postalCode", "Postalcode");
		propertyToLabelMap.put("address.city", "City");
		propertyToLabelMap.put("age", "Age");
		propertyToLabelMap.put("birthday", "Birthday");
		propertyToLabelMap.put("money", "Money");
		propertyToLabelMap.put("description", "Description");
		propertyToLabelMap.put("favouriteFood", "Food");
		propertyToLabelMap.put("favouriteDrinks", "Drinks");

		IColumnPropertyAccessor<ExtendedPersonWithAddress> columnPropertyAccessor = 
				new ExtendedReflectiveColumnPropertyAccessor<ExtendedPersonWithAddress>(propertyNames);

		BodyLayerStack<ExtendedPersonWithAddress> bodyLayer = 
				new BodyLayerStack<ExtendedPersonWithAddress>(PersonService.getExtendedPersonsWithAddress(10), 
						columnPropertyAccessor, 
						sndColumnGroupModel, columnGroupModel);

		IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
		DataLayer columnHeaderDataLayer = new DataLayer(columnHeaderDataProvider);
		ILayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());
		
		SortHeaderLayer<ExtendedPersonWithAddress> sortHeaderLayer = 
				new SortHeaderLayer<ExtendedPersonWithAddress>(columnHeaderLayer, 
					new GlazedListsSortModel<ExtendedPersonWithAddress>(bodyLayer.getSortedList(), 
							columnPropertyAccessor, configRegistry, columnHeaderDataLayer));
		
		ColumnGroupHeaderLayer columnGroupHeaderLayer = new ColumnGroupHeaderLayer(sortHeaderLayer, bodyLayer.getSelectionLayer(), columnGroupModel);

		columnGroupHeaderLayer.addColumnsIndexesToGroup("Person", 0, 1, 2, 3);
		columnGroupHeaderLayer.addColumnsIndexesToGroup("Address", 4, 5, 6, 7);
		columnGroupHeaderLayer.addColumnsIndexesToGroup("Facts", 8, 9, 10);
		columnGroupHeaderLayer.addColumnsIndexesToGroup("Personal", 11, 12, 13);
		
		columnGroupHeaderLayer.setStaticColumnIndexesByGroup("Person", 0, 1);
		columnGroupHeaderLayer.setStaticColumnIndexesByGroup("Address", 4, 5, 6);
		
		ColumnGroupGroupHeaderLayer sndGroup = 
				new ColumnGroupGroupHeaderLayer(columnGroupHeaderLayer, bodyLayer.getSelectionLayer(), sndColumnGroupModel);
		
		sndGroup.addColumnsIndexesToGroup("PersonWithAddress", 0, 1, 2, 3, 4, 5, 6, 7);
		sndGroup.addColumnsIndexesToGroup("Additional Information", 8, 9, 10, 11, 12, 13);

		sndGroup.setStaticColumnIndexesByGroup("PersonWithAddress", 0, 1);
		
		//	Note: The column header layer is wrapped in a filter row composite.
		//	This plugs in the filter row functionality
		FilterRowHeaderComposite<ExtendedPersonWithAddress> filterRowHeaderLayer =
			new FilterRowHeaderComposite<ExtendedPersonWithAddress>(
					new DefaultGlazedListsFilterStrategy<ExtendedPersonWithAddress>(bodyLayer.getFilterList(), columnPropertyAccessor, configRegistry),
					sndGroup, columnHeaderDataLayer.getDataProvider(), configRegistry
			);

		DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyLayer.getBodyDataProvider());
		DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
		rowHeaderDataLayer.setDefaultColumnWidth(40);
		ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, bodyLayer, bodyLayer.getSelectionLayer());

		ILayer cornerLayer = new CornerLayer(
				new DataLayer(
						new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider)), 
						rowHeaderLayer, filterRowHeaderLayer);
		
		GridLayer gridLayer = new GridLayer(bodyLayer, filterRowHeaderLayer, rowHeaderLayer, cornerLayer);

		NatTable natTable = new NatTable(parent, gridLayer, false);
		natTable.setConfigRegistry(configRegistry);
		natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
		//add filter row configuration
		natTable.addConfiguration(new FilterRowConfiguration());
		
		natTable.configure();

		return natTable;
	}
	
	
	class BodyLayerStack<T> extends AbstractLayerTransform {
		
		private final SortedList<T> sortedList;
		private final FilterList<T> filterList;
		
		private final IDataProvider bodyDataProvider;

		private ColumnReorderLayer columnReorderLayer;
		private ColumnGroupReorderLayer columnGroupReorderLayer;
		private ColumnHideShowLayer columnHideShowLayer;
		private ColumnGroupExpandCollapseLayer columnGroupExpandCollapseLayer;
		private SelectionLayer selectionLayer;
		private ViewportLayer viewportLayer;

		public BodyLayerStack(List<T> values, IColumnPropertyAccessor<T> columnPropertyAccessor, 
				ColumnGroupModel... columnGroupModel) {
			//wrapping of the list to show into GlazedLists
			//see http://publicobject.com/glazedlists/ for further information
			EventList<T> eventList = GlazedLists.eventList(values);
			TransformedList<T, T> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
			
			//use the SortedList constructor with 'null' for the Comparator because the Comparator
			//will be set by configuration
			this.sortedList = new SortedList<T>(rowObjectsGlazedList, null);
			// wrap the SortedList with the FilterList
			this.filterList = new FilterList<T>(getSortedList());
			
			this.bodyDataProvider = 
				new ListDataProvider<T>(filterList, columnPropertyAccessor);
			DataLayer bodyDataLayer = new DataLayer(this.bodyDataProvider);
			
			//layer for event handling of GlazedLists and PropertyChanges
			GlazedListsEventLayer<T> glazedListsEventLayer = 
				new GlazedListsEventLayer<T>(bodyDataLayer, filterList);

			columnReorderLayer = new ColumnReorderLayer(glazedListsEventLayer);
			columnGroupReorderLayer = new ColumnGroupReorderLayer(columnReorderLayer, columnGroupModel[columnGroupModel.length-1]);
			columnHideShowLayer = new ColumnHideShowLayer(columnGroupReorderLayer);
			columnGroupExpandCollapseLayer = new ColumnGroupExpandCollapseLayer(columnHideShowLayer, columnGroupModel);
			selectionLayer = new SelectionLayer(columnGroupExpandCollapseLayer);
			viewportLayer = new ViewportLayer(selectionLayer);
			setUnderlyingLayer(viewportLayer);
		}

		public SortedList<T> getSortedList() {
			return sortedList;
		}
		
		public FilterList<T> getFilterList() {
			return filterList;
		}

		public IDataProvider getBodyDataProvider() {
			return bodyDataProvider;
		}

		public ColumnReorderLayer getColumnReorderLayer() {
			return columnReorderLayer;
		}

		public ColumnGroupReorderLayer getColumnGroupReorderLayer() {
			return columnGroupReorderLayer;
		}

		public ColumnHideShowLayer getColumnHideShowLayer() {
			return columnHideShowLayer;
		}

		public ColumnGroupExpandCollapseLayer getColumnGroupExpandCollapseLayer() {
			return columnGroupExpandCollapseLayer;
		}

		public SelectionLayer getSelectionLayer() {
			return selectionLayer;
		}

		public ViewportLayer getViewportLayer() {
			return viewportLayer;
		}

	}

	/**
	 * The configuration to enable the edit mode for the grid and additional
	 * edit configurations like converters and validators.
	 * 
	 * @author Dirk Fauth
	 */
	class FilterRowConfiguration extends AbstractRegistryConfiguration {

		@Override
		public void configureRegistry(IConfigRegistry configRegistry) {

			//register the FilterRowTextCellEditor in the first column which immediately commits on key press
			configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, 
					new FilterRowTextCellEditor(), 
					DisplayMode.NORMAL, 
					FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + DataModelConstants.FIRSTNAME_COLUMN_POSITION);
			
			//register a combo box cell editor for the gender column in the filter row
			//the label is set automatically to the value of 
			//FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + column position
			ICellEditor comboBoxCellEditor = new ComboBoxCellEditor(Arrays.asList(Gender.FEMALE, Gender.MALE));
			configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, 
					comboBoxCellEditor, 
					DisplayMode.NORMAL, 
					FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + DataModelConstants.GENDER_COLUMN_POSITION);

			
			//register a combo box cell editor for the married column in the filter row
			//the label is set automatically to the value of 
			//FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + column position
			comboBoxCellEditor = new ComboBoxCellEditor(Arrays.asList(Boolean.TRUE, Boolean.FALSE));
			configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, 
					comboBoxCellEditor, 
					DisplayMode.NORMAL, 
					FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + DataModelConstants.MARRIED_COLUMN_POSITION);
			
			configRegistry.registerConfigAttribute(
					FilterRowConfigAttributes.TEXT_MATCHING_MODE, 
					TextMatchingMode.EXACT, 
					DisplayMode.NORMAL, 
					FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + DataModelConstants.GENDER_COLUMN_POSITION);

			configRegistry.registerConfigAttribute(FilterRowConfigAttributes.TEXT_DELIMITER, "&"); //$NON-NLS-1$

		}

	}
}
Re: Misbehaving two-level column groups [message #1281698 is a reply to message #1281380] Tue, 01 April 2014 08:22 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Hello Dirk,

Thanks for the answer! Yes, i'm using static columns. My layer topology seems to be right according to your code, but i created a graph about it, if you have a minute please take a look on it.

http://s8.postimg.org/yvga6numd/nattable.png

I also created a video about the overflow glitch:

https://www.youtube.com/watch?v=BAt78UYEhvk

When i tried to solve this issue, i first started to debug getColumnSpan in ColumnGroupGroupHeaderLayer. I noticed that this method somehow takes into account if a column is not visible. For example, if there is a column group with 8 columns, and 4 of those columns are scrolled off the screen, getColumnSpan returns 4 in ColumnGroupGroupHeaderLayer. But when the group is collapsed, it returns the number of static columns, which does not seem to be the correct value for me.

For now, my solution is to override getColumnSpan() with this code:

@Override
protected int getColumnSpan(int columnPosition) {
	int columnIndex = getColumnIndexByPosition(columnPosition);
	final ColumnGroup columnGroup = model.getColumnGroupByIndex(columnIndex);
	int leastPossibleStartPositionOfGroup = columnPosition - (columnGroup.getSize() - 1);
	int i = 0;
	for (i = leastPossibleStartPositionOfGroup; i < columnPosition; i++) {
		if (ColumnGroupUtils.isInTheSameGroup(getColumnIndexByPosition(i), columnIndex, model)) {
			break;
		}
	}
	int sizeOfGroup = columnGroup.getSize();
	int endPositionOfGroup = i + sizeOfGroup;
	final List<Integer> columnIndexesInGroup = columnGroup.getMembers();
	for (; i < endPositionOfGroup; i++) {
		int index = getColumnIndexByPosition(i);
		if (!columnIndexesInGroup.contains(Integer.valueOf(index))) {
			sizeOfGroup--;
		}
	}
	return sizeOfGroup;
}


This is a mixture of the super implementation of getColumnpan() and getStartPositionOfGroup() since it's not visible for extending classes.

I also tried this solution when there are no static columns defined. In this case, when the group is collapsed, only the first column is visible, scrolling works properly, the group does not vanish.
Re: Misbehaving two-level column groups [message #1281729 is a reply to message #1281698] Tue, 01 April 2014 09:15 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
Are you able to reproduce the issue in my example?

Are you using the latest development snapshot build? http://download.eclipse.org/nattable/snapshots/

What ICellPainters do you use with which styling? Because I can also see in your video that the text is moving on scrolling, which should be the case by default.
Re: Misbehaving two-level column groups [message #1282352 is a reply to message #1281729] Wed, 02 April 2014 07:01 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
I tested your workaround, and in first place it looks ok, but running the test cases you will notice that your implementation has a bug. It will return a column span even if there is only one column visible because of the collapsed state.

The broken test case assumes that there are no static columns. So on collapsing the first column will be shown. In that case there is no column span as there is only one column shown. Your implementation will return the values for all columns in the group. That is wrong.

While I implemented the example I came across an issue that is hard to identify. On rendering there might occur issues if you created the layers with wrong dependent layers. For example, if you created your ColumnGroupGroupHeaderLayer with the reference to the ColumnHeaderLayer instead of the ColumnGroupHeaderLayer, the dimensional dependency is wrong and therefore the calculation is wrong. As I said in my previous post, the issue that the center aligned text in your column group group header is also moving on scrolling looks like some general issue that I can not reproduce in my example.

Please check your layer stacking again to see if the issue is hidden there.
Re: Misbehaving two-level column groups [message #1282360 is a reply to message #1282352] Wed, 02 April 2014 07:18 Go to previous messageGo to next message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Hello Dirk,

i'm using the latest snapshot. Your example only needs a little modification to expose the flaw (if it's really a flaw).

Change the very end of the BodyLayerStack's constructor to:

viewportLayer = new ViewportLayer(selectionLayer);
FreezeLayer freezeLayer = new FreezeLayer(selectionLayer);
CompositeFreezeLayer compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
setUnderlyingLayer(compositeFreezeLayer);


This way the scrolling text issues comes up as well as the overflowing issue when the group is collapsed.

To be honest, i like the scrolling text "issue", i thought that was a feature Smile It is useful because the column header text remains readable as long as possible.

So it seems the freeze layer causes the problem. Is this the correct way to introduce the freeze layer?

About cell painters: nothing special, i use the following configuration for group group header:

final ICellPainter textPainter = new TextPainter(true, true);
final ICellPainter padddingPainter = new PaddingDecorator(textPainter, 4);
final ICellPainter borderPainter = new LineBorderDecorator(padddingPainter);
final ICellPainter sortHeaderPainter = new PaddingDecorator(
		new SortableHeaderTextPainter(borderPainter, true, false), 0, 2, 0, 0);
final ICellPainter columnGroupHeaderPainter = new ColumnGroupHeaderTextPainter(padddingPainter);

[Updated on: Wed, 02 April 2014 07:20]

Report message to a moderator

Re: Misbehaving two-level column groups [message #1282589 is a reply to message #1282360] Wed, 02 April 2014 14:49 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
My investigations so far:

The reason for the misbehaviour is indeed the CompositeFreezeLayer. While the ViewportLayer is able to translate negative column positions to correct indexes, the CompositeFreezeLayer is not.

Quote:
To be honest, i like the scrolling text "issue", i thought that was a feature Smile It is useful because the column header text remains readable as long as possible.


IMHO such a behaviour hurts the specification of scrolling, where content should be moved out of the visible area and not jump around. Of course this is some kind of personal flavour, but the default behaviour should be scrolling not jumping. Wink

I will investigate further for possible solutions.
Re: Misbehaving two-level column groups [message #1283808 is a reply to message #1282589] Thu, 03 April 2014 21:06 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2704
Registered: July 2012
Senior Member
I think I fixed the issue by modifying the getColumnSpan() method. I tried to also fix the column group text jumping on scrolling, but that would mean to rewrite the CompositeLayer. Still not sure how. As such refactorings will not happen in this architecture and of course not prior a release, this "feature" stays. Wink

Could you please verify that the latest changes I pushed fix the issue?
Re: Misbehaving two-level column groups [message #1284308 is a reply to message #1283808] Fri, 04 April 2014 10:24 Go to previous message
Istvan Meszaros is currently offline Istvan MeszarosFriend
Messages: 49
Registered: October 2009
Member
Hello Dirk,

thank you very much for your effort, the latest snapshot solved the issue! Smile
Previous Topic:NatTable scroll bar appears all time when event list is cleared
Next Topic:Reorder Column Groups inconsistent column position
Goto Forum:
  


Current Time: Fri Aug 23 13:29:29 GMT 2019

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

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

Back to the top