Vaadin Treetable Example
If you need to show rows of data in a Hierarchical structure, Vaadin offers the TreeTable widget that can arrange these kind of data for you without much effort. In this example I am going to build a TreeTable to show these kind of data visualization.
1. The tools
- Java JDK 8
- Latest Eclipse Mars
- Vaadin 7.6.3
- Tomcat Server 8
2. Introduction
The TreeTable widget is an extension of the Table widget, and the rows of the table have a parent-children relationship with each other. If you have rows with no parent the TreeTable put those items on the root of the tree otherwise you need to explicit declare the parent of the row.
3. Prerequisites
- JDK installed
- Eclipse Mars installed and working
- Vaadin 7.6.3 plugin installed
- Tomcat 8 installed and running
4. Set up the project
In the file menu choose File -> New -> Other:
Now from the list choose Vaadin 7 project:
Hit next and name your project then hit finish.
5. Coding the example
Inside the init method.
Layout
final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout);
First I create the Layout, in this case a vertical layout to put the TreeTable.
Create the TreeTable
TreeTable tt = new TreeTable("Some Linux Distros ..."); tt.setWidth("100%"); tt.addContainerProperty("Name", String.class, null); tt.addContainerProperty("Year", String.class, null);
Create the TreeTable, set it’s width to 100% to make it looks better for the example, add two columns, the “Name” and Year columns of String type with a default value of null
.
First root
tt.addItem(new Object[] {"Debian", "1993"}, 0);
Add the “Debian” node with ID 0 with no parent so it’s show in the root of the tree.
First child
tt.addItem(new Object[] {"Knoppix", "2000"}, 1); tt.setParent(1, 0);
The item “Knoppix”, have an ID of 1 and with the call to the method tt.setParent(1, 0);
I am telling to Vaadin that make the item with ID 1 a child of the item with the ID 0.
Rest of the first branch of the first root
tt.addItem(new Object[] {"Knotix", "2003"}, 2); tt.setParent(2, 1); tt.addItem(new Object[] {"Auditor Security Linux", "2004"}, 3); tt.setParent(3, 2); tt.addItem(new Object[] {"Backtrack", "2006"}, 4); tt.setParent(4, 3); tt.addItem(new Object[] {"Kali Linux", "2013"}, 5); tt.setParent(5, 4);
I added “Kali Linux” as a child of “Backtrack”, “Backtrack” as a child of “Auditor Security Linux”, “Auditor Security Linux” as a child of “Knotix” and Knotix as a child of “Knoppix”, the relationship is controlled with the ID’s and the setParent
method.
Second branch of the first root
tt.addItem(new Object[] {"Ubuntu", "2004"}, 20); tt.setParent(20, 0); tt.addItem(new Object[] {"Mint", "2006"}, 21); tt.setParent(21, 20); tt.addItem(new Object[] {"Lubuntu", "2009"}, 22); tt.setParent(22, 20); tt.addItem(new Object[] {"Elementary OS", "2011"}, 23); tt.setParent(23, 20);
In this branch we have a single node with 3 children, note the id, these must be unique without collisions, the node with the id 20 is the parent and the nodes with the id’s 21, 22, 23 are it’s children in the same level.
Second root branch
tt.addItem(new Object[] {"SLS", "1992"}, 30); tt.addItem(new Object[] {"Slackware", "1993"}, 31); tt.setParent(31, 30); tt.addItem(new Object[] {"S.u.S.E", "1994"}, 32); tt.setParent(32, 31); tt.addItem(new Object[] {"SuSE", "1998"}, 33); tt.setParent(33, 32); tt.addItem(new Object[] {"SUSE", "2003"}, 34); tt.setParent(34, 33); tt.addItem(new Object[] {"openSUSE", "2006"}, 35); tt.setParent(35, 34);
In this branch we have a linear relationship with each item, the root have one children and each subsequent node have only one children to the bottom of the branch.
Third root branch
tt.addItem(new Object[] {"Red Hat", "1994"}, 40);
This root node have a single item without children and is added in order behind the two other root nodes.
Row click listener
final Label current = new Label("Selected: NONE"); tt.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { if(tt.getValue() != null){ current.setValue("Selected: " + tt.getItem(tt.getValue()).toString()); }else{ current.setValue("Selected: NONE"); } } });
Create a Label to show when a row is selected and if a row is selected show the value of the row. Using the value change listener is possible to capture when a row is selected or unselected and do whatever we want when this action is performed.
Header click listener
tt.addHeaderClickListener(new HeaderClickListener() { @Override public void headerClick(HeaderClickEvent event) { String column = (String) event.getPropertyId(); Notification.show("Column: " + column + " Mouse Button: " + event.getButtonName()); } });
With a header click listener we can capture if the user click in the header of the column and also with the getButtonName()
method is possible to get the button used to click in the header of the column. When you click with the left button of the mouse in the header of the TreeTable, you can order the rows of the tree table and this functionality is build in into the widget.
Add widgets to the layout
layout.addComponent(current); layout.addComponent(tt);
Add the Label
and the TreeTable
to the layout.
6. The complete source code
java
package com.example.vaadintreetable; import javax.servlet.annotation.WebServlet; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Table.HeaderClickEvent; import com.vaadin.ui.Table.HeaderClickListener; import com.vaadin.ui.TreeTable; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; @SuppressWarnings("serial") @Theme("vaadintreetable") public class VaadintreetableUI extends UI { @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadintreetableUI.class) public static class Servlet extends VaadinServlet { } @Override protected void init(VaadinRequest request) { final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout); TreeTable tt = new TreeTable("Some Linux Distros ..."); tt.setWidth("100%"); tt.addContainerProperty("Name", String.class, null); tt.addContainerProperty("Year", String.class, null); tt.addItem(new Object[] {"Debian", "1993"}, 0); tt.addItem(new Object[] {"Knoppix", "2000"}, 1); tt.setParent(1, 0); tt.addItem(new Object[] {"Knotix", "2003"}, 2); tt.setParent(2, 1); tt.addItem(new Object[] {"Auditor Security Linux", "2004"}, 3); tt.setParent(3, 2); tt.addItem(new Object[] {"Backtrack", "2006"}, 4); tt.setParent(4, 3); tt.addItem(new Object[] {"Kali Linux", "2013"}, 5); tt.setParent(5, 4); tt.addItem(new Object[] {"Ubuntu", "2004"}, 20); tt.setParent(20, 0); tt.addItem(new Object[] {"Mint", "2006"}, 21); tt.setParent(21, 20); tt.addItem(new Object[] {"Lubuntu", "2009"}, 22); tt.setParent(22, 20); tt.addItem(new Object[] {"Elementary OS", "2011"}, 23); tt.setParent(23, 20); tt.addItem(new Object[] {"SLS", "1992"}, 30); tt.addItem(new Object[] {"Slackware", "1993"}, 31); tt.setParent(31, 30); tt.addItem(new Object[] {"S.u.S.E", "1994"}, 32); tt.setParent(32, 31); tt.addItem(new Object[] {"SuSE", "1998"}, 33); tt.setParent(33, 32); tt.addItem(new Object[] {"SUSE", "2003"}, 34); tt.setParent(34, 33); tt.addItem(new Object[] {"openSUSE", "2006"}, 35); tt.setParent(35, 34); tt.addItem(new Object[] {"Red Hat", "1994"}, 40); final Label current = new Label("Selected: NONE"); tt.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { if(tt.getValue() != null){ current.setValue("Selected: " + tt.getItem(tt.getValue()).toString()); }else{ current.setValue("Selected: NONE"); } } }); tt.addHeaderClickListener(new HeaderClickListener() { @Override public void headerClick(HeaderClickEvent event) { String column = (String) event.getPropertyId(); Notification.show("Column: " + column + " Mouse Button: " + event.getButtonName()); } }); layout.addComponent(current); layout.addComponent(tt); } }
7. Running the example
Right click on the project folder and choose Run as -> Run on server choose Tomcat 8 server and hit finish.
8. Results
The results of the example, you can see the TreeTable in action.
9. Download the Source Code
This was an example about Vaadin Treetable.
You can download the Eclipse project here: VaadinTreeTable
Is it possible to sort ONLY the parent elements of a tree table? For example, from your image, we would only sort among “SLS”, “Debian” and “RedHat”.
I have been trying to do something similar to that, and I couldn’t figure out how to “skip” the children elements while sorting.
Any help is appreciated :)
Thanks!