Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » How to combine two nattables (so that they appear to be one)
How to combine two nattables (so that they appear to be one) [message #1691969] Sat, 11 April 2015 08:13 Go to next message
Thorsten Schlathölter is currently offline Thorsten SchlathölterFriend
Messages: 312
Registered: February 2012
Location: Düsseldorf
Senior Member
Hi,
I have a question regarding the possibility to combine two nattables.

This is hte scenario:
I have a complex grid which extensively uses the SpanningDataLayer. The table has a complex header part which has different columns than the rest of the table (it would actually also make use of a SpanningDataLayer). If the columns of the grid are resized, the header should not change. So the idea is to implement the header in an individual table and just display it above the main grid. Ideally the columns of the main grid should be displayed on top of the header table. The header table itself does not need to display column headers. If possible both tables should be displayed in one viewport. So vertical scrolling should also move the header table.

Is it somehow possible to achieve this (or smething close to this) with nattable?

Thanks in advance
Thorsten
Re: How to combine two nattables (so that they appear to be one) [message #1691973 is a reply to message #1691969] Sat, 11 April 2015 10:18 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
Yes - No - it depends

There is typically no need to combine two NatTable instances, since you are able to compose your NatTable via layers. This means you could create two layer stacks and create a correlation. This by the way is the same the GridLayer does.

Now the default setup is that the column header and the body are dimensionally dependent. It sounds like you don't want that dependency. Although I'm not sure how you want to create some correlation without a dimensional dependency. But that seems to be part of your complex composition.

It is also possible to have two ViewportLayer in one layer composition. Have a look at the ViewportLayer examples where we show how to create compositions with a split viewport. It detail you are replacing the default scrollbar with a custom scrollbar.

If you really want to attach two NatTable instances to each other, this might be also sufficient. I also wrote a blog post about replacing the scrollbars. So maybe that helps too: http://blog.vogella.com/2015/01/26/nattable-with-custom-scrollbars/
Re: How to combine two nattables (so that they appear to be one) [message #1691987 is a reply to message #1691973] Sat, 11 April 2015 14:57 Go to previous messageGo to next message
Thorsten Schlathölter is currently offline Thorsten SchlathölterFriend
Messages: 312
Registered: February 2012
Location: Düsseldorf
Senior Member
Thank you very much for the quick response.
I already tried to use a composite layer with two data layers and a header layer. I think that is what you propose.
I used the VerticalCompositionExample as a starting point, simply created a new data layer with only 2 columns and added it in between the column header and the original data layer.
The second data layer should span the whole table. So I set the layer to percentage resizing. Unfortunately the columns of the original data layer overlapp my second data layer columns.
That is why I thought I need to use two individual tables.

Is the Nattable able to manage this scenario and am I just doing something wrong?

Thanks in advance.
Thorsten

Here is the code I used:
[code][
/*******************************************************************************
* Copyright (c) 2013 Dirk Fauth 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:
* Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.nattable.examples._500_Layers._503_Compositions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.nebula.widgets.nattable.NatTable;
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.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.data.person.Person;
import org.eclipse.nebula.widgets.nattable.examples.data.person.PersonService;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
* Example showing a NatTable that contains a column header and a body layer.
*
* @author Dirk Fauth
*
*/
public class CopyOf_5031_VerticalCompositionExample extends AbstractNatExample {

public static void main(String[] args) throws Exception {
StandaloneNatExampleRunner.run(600, 400,
new CopyOf_5031_VerticalCompositionExample());
}

@Override
public String getDescription() {
return "This example shows how to assemble a table that consists of a column header and a body layer.";
}

@Override
public Control createExampleControl(Composite parent) {
// property names of the Person class
String[] propertyNames1 = { "firstName", "lastName", "gender",
"married", "birthday" };
String[] propertyNames2 = { "firstName", "lastName" };

// 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("birthday", "Birthday");

IColumnPropertyAccessor<Person> columnPropertyAccessor1 = new ReflectiveColumnPropertyAccessor<Person>(
propertyNames1);
IColumnPropertyAccessor<Person> columnPropertyAccessor2 = new ReflectiveColumnPropertyAccessor<Person>(
propertyNames2);

final List<Person> data = PersonService.getPersons(10);

IDataProvider bodyDataProvider = new ListDataProvider<Person>(data,
columnPropertyAccessor1);
final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);

final SelectionLayer selectionLayer = new SelectionLayer(bodyDataLayer);
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

IDataProvider bodyDataProvider2 = new ListDataProvider<Person>(data,
columnPropertyAccessor2);
final DataLayer bodyDataLayer2 = new DataLayer(bodyDataProvider2);
bodyDataLayer2.setColumnPercentageSizing(true);
ILayer columnHeaderLayer = new ColumnHeaderLayer(new DataLayer(
new DefaultColumnHeaderDataProvider(propertyNames1,
propertyToLabelMap)), viewportLayer, selectionLayer);

// set the region labels to make default configurations work, e.g.
// selection
CompositeLayer compositeLayer = new CompositeLayer(1, 3);
compositeLayer.setChildLayer(GridRegion.COLUMN_HEADER,
columnHeaderLayer, 0, 0);
compositeLayer.setChildLayer(GridRegion.BODY, viewportLayer, 0, 2);
compositeLayer.setChildLayer(GridRegion.BODY, bodyDataLayer2, 0, 1);

return new NatTable(parent, compositeLayer);
}

}

/code]
Re: How to combine two nattables (so that they appear to be one) [message #1691988 is a reply to message #1691973] Sat, 11 April 2015 14:57 Go to previous messageGo to next message
Thorsten Schlathölter is currently offline Thorsten SchlathölterFriend
Messages: 312
Registered: February 2012
Location: Düsseldorf
Senior Member
Thank you very much for the quick response.
I already tried to use a composite layer with two data layers and a header layer. I think that is what you propose.
I used the VerticalCompositionExample as a starting point, simply created a new data layer with only 2 columns and added it in between the column header and the original data layer.
The second data layer should span the whole table. So I set the layer to percentage resizing. Unfortunately the columns of the original data layer overlapp my second data layer columns.
That is why I thought I need to use two individual tables.

Is the Nattable able to manage this scenario and am I just doing something wrong?

Thanks in advance.
Thorsten

Here is the code I used:
[code][
/*******************************************************************************
* Copyright (c) 2013 Dirk Fauth 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:
* Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.nattable.examples._500_Layers._503_Compositions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.nebula.widgets.nattable.NatTable;
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.examples.AbstractNatExample;
import org.eclipse.nebula.widgets.nattable.examples.data.person.Person;
import org.eclipse.nebula.widgets.nattable.examples.data.person.PersonService;
import org.eclipse.nebula.widgets.nattable.examples.runner.StandaloneNatExampleRunner;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
* Example showing a NatTable that contains a column header and a body layer.
*
* @author Dirk Fauth
*
*/
public class CopyOf_5031_VerticalCompositionExample extends AbstractNatExample {

public static void main(String[] args) throws Exception {
StandaloneNatExampleRunner.run(600, 400,
new CopyOf_5031_VerticalCompositionExample());
}

@Override
public String getDescription() {
return "This example shows how to assemble a table that consists of a column header and a body layer.";
}

@Override
public Control createExampleControl(Composite parent) {
// property names of the Person class
String[] propertyNames1 = { "firstName", "lastName", "gender",
"married", "birthday" };
String[] propertyNames2 = { "firstName", "lastName" };

// 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("birthday", "Birthday");

IColumnPropertyAccessor<Person> columnPropertyAccessor1 = new ReflectiveColumnPropertyAccessor<Person>(
propertyNames1);
IColumnPropertyAccessor<Person> columnPropertyAccessor2 = new ReflectiveColumnPropertyAccessor<Person>(
propertyNames2);

final List<Person> data = PersonService.getPersons(10);

IDataProvider bodyDataProvider = new ListDataProvider<Person>(data,
columnPropertyAccessor1);
final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);

final SelectionLayer selectionLayer = new SelectionLayer(bodyDataLayer);
ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);

IDataProvider bodyDataProvider2 = new ListDataProvider<Person>(data,
columnPropertyAccessor2);
final DataLayer bodyDataLayer2 = new DataLayer(bodyDataProvider2);
bodyDataLayer2.setColumnPercentageSizing(true);
ILayer columnHeaderLayer = new ColumnHeaderLayer(new DataLayer(
new DefaultColumnHeaderDataProvider(propertyNames1,
propertyToLabelMap)), viewportLayer, selectionLayer);

// set the region labels to make default configurations work, e.g.
// selection
CompositeLayer compositeLayer = new CompositeLayer(1, 3);
compositeLayer.setChildLayer(GridRegion.COLUMN_HEADER,
columnHeaderLayer, 0, 0);
compositeLayer.setChildLayer(GridRegion.BODY, viewportLayer, 0, 2);
compositeLayer.setChildLayer(GridRegion.BODY, bodyDataLayer2, 0, 1);

return new NatTable(parent, compositeLayer);
}

}

/code]
Re: How to combine two nattables (so that they appear to be one) [message #1691990 is a reply to message #1691988] Sat, 11 April 2015 15:15 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
No that was not what I proposed. From your example now it more looks like a composition we use for the groupBy feature. There we wrap the grid in a composite and add the GroupByHeaderLayer at position 0 and the grid at 1. Also you need to implement the dimensional dependency by yourself in such a composition. Setting a separate column sizing will not work out. Have a look at the GroupByHeaderLayer as an example. But of course there you will have the issue that the top layer won't scroll.

There are additional examples for split viewports. But you could also try to implement the dimensional dependency in a way that it is able to scroll.
Re: How to combine two nattables (so that they appear to be one) [message #1692022 is a reply to message #1691990] Sun, 12 April 2015 10:38 Go to previous messageGo to next message
Thorsten Schlathölter is currently offline Thorsten SchlathölterFriend
Messages: 312
Registered: February 2012
Location: Düsseldorf
Senior Member
Thanks again for this valuable input. I will have a look into this example. I have attached an image of the kind of table I am trying to reproduce with the nattable. I would very much appreciate if you could have a look at at that image and tell me what approach you would favour in order to model this kind of table with the nattable. The restriction to the table is that hte first three rows should be fixed in layout. So changes in column width of the main table should not be reflected in the header.

Regards,
Thorsten
  • Attachment: table.jpg
    (Size: 218.32KB, Downloaded 167 times)
Re: How to combine two nattables (so that they appear to be one) [message #1692024 is a reply to message #1692022] Sun, 12 April 2015 10:57 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
I really don't understand why you in that case need to have the two tables combined or handled like one. Nevertheless, if those two tables don't have any correlation, I don't see why they need to be connected. There will UX issues arise later regarding resizing and scrolling.

But to answer your question, for me it looks like you need a different composite on top. Maybe a non-scrollable NatTable wrapped in a scrollable composite with non visible scrollbars. And then link the NatTable with that composite on scrolling. Something like that.
Re: How to combine two nattables (so that they appear to be one) [message #1692061 is a reply to message #1692024] Mon, 13 April 2015 06:39 Go to previous message
Thorsten Schlathölter is currently offline Thorsten SchlathölterFriend
Messages: 312
Registered: February 2012
Location: Düsseldorf
Senior Member
Putting two nattables on top of each other perfectly suits my needs. Maybe the topic of this thread is a little missleading. There are of course some issues. It would for example be great if the whole structure could be exported to excel as is. Therefor I just wanted to know if the approach to use two tables is the right one or if there are ways to achieve this with one table.

Thanks for sharing your point of view. I have implemented it now with two tables and a vertical scrollbar using a specific IScroller.

Regards
Thorsten

Previous Topic:Problem with word wrap in Nattable
Next Topic:Freezelayer issue
Goto Forum:
  


Current Time: Wed Apr 24 22:56:39 GMT 2024

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

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

Back to the top