Vaadin Container Example
The relational model is the organization of data into collections of two-dimensional tables called relations, the relational data model was developed for databases but you can use this model to group sets of items and define relations between these sets, a container of sets of items and its relations.
1. The tools
- Java JDK 8
- Latest Eclipse Mars
- Vaadin 7.6.4
- Tomcat Server 8
2. Introduction
Vaadin Container is a set of Items, that have a relational model, you can use it to easily wrap a database and associate it with the Vaadin controls that implements the Container
interface. It’s use is not restricted to a database, you can use it to model your own sets of items and it’s relations inside your application, and get advantage of the strong structure that the Vaadin container provides. A container must follow certain rules to use it:
- Each Item have the same number of Properties.
- Each Item have an ID property.
- All Properties in different items must have the same data type.
- The Item ID of a container id unique and non-null.
In this example I am going to show how to use a Vaadin Container.
3. Prerequisites
- JDK installed
- Eclipse Mars installed and working
- Vaadin 7.6.4 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
5.1 MyBean BeanContainer
The BeanContainer is a container for JavaBean objects. It is a simple Java class that implements Serializable and has all the fields that we want in our container.
MyBean.java
package com.example.vaadincontainer; import java.io.Serializable; public class MyBean implements Serializable { private static final long serialVersionUID = 1L; private String name; private String surname; private MySubBean osUsed; public MyBean (String pname, String psurname, MySubBean pSubBean){ this.name = pname; this.surname = psurname; this.osUsed = pSubBean; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public MySubBean getOsUsed() { return osUsed; } public void setOsUsed(MySubBean osUsed) { this.osUsed = osUsed; } }
MyBean
has two string fields called name and surname and another bean which is called MySubBean with a parent-child relationship. This is a simple pojo Java class with the field declarations, a single constructor public MyBean (String pname, String psurname, MySubBean pSubBean)
and standard getters and setters for each property field. Also we have here MySuBean
fields that are the fields that define the nested relationship, having as a member another bean.
5.2 MySubBean BeanContainer
MySubBean.java
package com.example.vaadincontainer; import java.io.Serializable; public class MySubBean implements Serializable { private static final long serialVersionUID = 1L; private String os; public MySubBean(String pOs){ this.os = pOs; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } }
This is the child bean and has only one string field, to the purpose of this tutorial a nested bean is working. As before this is a simple pojo Java class that has the field declarations, a constructor, getters and setters.
5.3 The UI
5.3.1 Random name generator
Random OS
private MySubBean randomOS(){ Random osr = new Random(); int osn = osr.nextInt(5); String oss = ""; switch (osn) { case 0: oss = "Linux"; break; case 1: oss = "OSX"; break; case 2: oss = "Android"; break; case 3: oss = "Unix"; break; case 4: oss = "Windows 10"; break; default: oss = "Linux"; break; } return new MySubBean(oss); }
I created a function that generates random OS names. This function is going to be used to create our beans and to generate random names. First I create a random generator with Random osr = new Random();
then i generate a random integer between 0 and 4 with int osn = osr.nextInt(5);
and choose an OS name with a switch
statement.
5.3.2 The layout
The layout
final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout);
A vertical layout as a main content layout.
5.3.3 First BeanContainer
First BeanContainer
BeanContainer beans = new BeanContainer(MyBean.class); beans.addNestedContainerProperty("osUsed.os"); beans.setBeanIdProperty("name"); beans.addBean(new MyBean("John", "Doe", randomOS())); beans.addBean(new MyBean("Matt", "Foe", randomOS()));
First I create a BeanContainer
using MyBean.class
as the blue print. BeanContainer is an in-memory container for JavaBeans and the properties of the container are determined automatically by introspecting the used JavaBean class. beans.addNestedContainerProperty("osUsed.os");
declares the nested properties of the container. beans.setBeanIdProperty("name");
tells the container what is the ID of the container and with beans.addBean
we add two sample items to the container with the name, surname and a using the random os generator name.
5.3.4 Second BeanContainer
Second BeanContainer
BeanContainer filteredBeans = new BeanContainer(MyBean.class); filteredBeans.addNestedContainerProperty("osUsed.os"); filteredBeans.setBeanIdProperty("name"); filteredBeans.addBean(new MyBean("John", "Doe", randomOS())); filteredBeans.addBean(new MyBean("Matt", "Foe", randomOS())); Filter filter = new SimpleStringFilter("surname", "Doe", true, false); filteredBeans.addContainerFilter(filter);
This beam container is the same as the first container. I added a filter to show a filtered bean container. Filter filter = new SimpleStringFilter("surname", "Doe", true, false);
adds a string filter that only shows the items with surname “doe”, the case is indifferent in this particular filter. filteredBeans.addContainerFilter(filter);
associates the filter with the container.
5.3.5 Employee Table
Unfiltered Table
table = new Table("Employees", beans); table.setColumnHeader("osUsed.os", "OS Used"); table.setHeight("200px"); table.setVisibleColumns(new Object[]{"name","surname", "osUsed.os"});
When I create the table “table”, the bean container beans
is passed as a parameter. With this parameter we tell to the table to associate the data on the bean as a data source for the table. table.setColumnHeader("osUsed.os", "OS Used");
changes the name of the header that is the name of the variable to a humanized name. table.setVisibleColumns(new Object[]{"name","surname", "osUsed.os"});
, tells the table what columns are visible.
5.3.6 Doe’s Table
Filtered Table
Table famTable = new Table("Surname Doe", filteredBeans); famTable.setColumnHeader("osUsed.os", "OS Used"); famTable.setHeight("200px"); famTable.setVisibleColumns(new Object[]{"name","surname", "osUsed.os"});
This famTable
only shows items with surname “doe”, all other items are filtered, thanks to the filter added to the filteredBeans
bean container.
5.3.7 Dinamyc input
Input
TextField tname = new TextField("Name"); TextField tsurname = new TextField("Surname"); Button badd = new Button("Add");
I created two text fields and a button to add items using the UI.
5.3.8 Click listener
Button click listener
badd.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { if(!tname.isEmpty() && !tsurname.isEmpty()){ String ctName = tname.getValue(); String ctSurname = tsurname.getValue(); String result = findDuplicates(ctName, ctSurname); if(result.equals("name")){ Notification.show("Name is duplicate - not adding", Notification.Type.ERROR_MESSAGE); }else if(result.equals("surname")){ Notification.show("Surname is duplicate"); } beans.addBean(new MyBean(ctName, ctSurname, randomOS())); filteredBeans.addBean(new MyBean(ctName, ctSurname, randomOS())); }else{ Notification.show("Missing Data ...", Notification.Type.WARNING_MESSAGE); } } });
When you click the button, if(!tname.isEmpty() && !tsurname.isEmpty())
checks if the input is empty. If not empty, we get both values and find if a duplicate exists with String result = findDuplicates(ctName, ctSurname);.
If a duplicate exists in the name or in the surname a notification is send to the user. In any case the item is added to the bean, which itself avoids to add items with duplicate ID.
5.3.9 Find Duplicates
findDuplicates
private String findDuplicates(String pName, String pSurname){ for (Iterator i = table.getItemIds().iterator(); i.hasNext();) { String iid = (String) i.next(); Item item = table.getItem(iid); String currName = (String) item.getItemProperty("name").getValue(); String currSurname = (String) item.getItemProperty("surname").getValue(); if(pName.equals(currName)){ return "name"; } if(pSurname.equals(currSurname)){ return "surname"; } } return "none"; }
To find duplicates we need to iterate over the container, the table.getItemIds()
method of Container returns a Collection of items so you can iterate all the entire collection of items. String iid = (String) i.next();
gets the next item ID.Item item = table.getItem(iid);
gets the item using the ID. String currName = (String) item.getItemProperty("name").getValue();
, gets the value of the current item “name” property. String currSurname = (String) item.getItemProperty("surname").getValue();
gets the current surname.
6. The complete source code
VaadincontainerUI.java
package com.example.vaadincontainer; import java.util.Iterator; import java.util.Random; import javax.servlet.annotation.WebServlet; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.data.Container.Filter; import com.vaadin.data.Item; import com.vaadin.data.util.BeanContainer; import com.vaadin.data.util.filter.SimpleStringFilter; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; @SuppressWarnings("serial") @Theme("vaadincontainer") public class VaadincontainerUI extends UI { @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadincontainerUI.class) public static class Servlet extends VaadinServlet { } private Table table; @Override protected void init(VaadinRequest request) { final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout); BeanContainer beans = new BeanContainer(MyBean.class); beans.addNestedContainerProperty("osUsed.os"); beans.setBeanIdProperty("name"); beans.addBean(new MyBean("John", "Doe", randomOS())); beans.addBean(new MyBean("Matt", "Foe", randomOS())); BeanContainer filteredBeans = new BeanContainer(MyBean.class); filteredBeans.addNestedContainerProperty("osUsed.os"); filteredBeans.setBeanIdProperty("name"); filteredBeans.addBean(new MyBean("John", "Doe", randomOS())); filteredBeans.addBean(new MyBean("Matt", "Foe", randomOS())); Filter filter = new SimpleStringFilter("surname", "Doe", true, false); filteredBeans.addContainerFilter(filter); table = new Table("Employees", beans); table.setColumnHeader("osUsed.os", "OS Used"); table.setHeight("200px"); table.setVisibleColumns(new Object[]{"name","surname", "osUsed.os"}); Table famTable = new Table("Surname Doe", filteredBeans); famTable.setColumnHeader("osUsed.os", "OS Used"); famTable.setHeight("200px"); famTable.setVisibleColumns(new Object[]{"name","surname", "osUsed.os"}); TextField tname = new TextField("Name"); TextField tsurname = new TextField("Surname"); Button badd = new Button("Add"); badd.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { if(!tname.isEmpty() && !tsurname.isEmpty()){ String ctName = tname.getValue(); String ctSurname = tsurname.getValue(); String result = findDuplicates(ctName, ctSurname); if(result.equals("name")){ Notification.show("Name is duplicate - not adding", Notification.Type.ERROR_MESSAGE); }else if(result.equals("surname")){ Notification.show("Surname is duplicate"); } beans.addBean(new MyBean(ctName, ctSurname, randomOS())); filteredBeans.addBean(new MyBean(ctName, ctSurname, randomOS())); }else{ Notification.show("Missing Data ...", Notification.Type.WARNING_MESSAGE); } } }); HorizontalLayout hl = new HorizontalLayout(); hl.addComponent(tname); hl.addComponent(tsurname); layout.addComponent(hl); layout.addComponent(badd); HorizontalLayout hlTab = new HorizontalLayout(); hlTab.addComponent(table); hlTab.addComponent(famTable); layout.addComponent(hlTab); } private String findDuplicates(String pName, String pSurname){ for (Iterator i = table.getItemIds().iterator(); i.hasNext();) { String iid = (String) i.next(); Item item = table.getItem(iid); String currName = (String) item.getItemProperty("name").getValue(); String currSurname = (String) item.getItemProperty("surname").getValue(); if(pName.equals(currName)){ return "name"; } if(pSurname.equals(currSurname)){ return "surname"; } } return "none"; } private MySubBean randomOS(){ Random osr = new Random(); int osn = osr.nextInt(5); String oss = ""; switch (osn) { case 0: oss = "Linux"; break; case 1: oss = "OSX"; break; case 2: oss = "Android"; break; case 3: oss = "Unix"; break; case 4: oss = "Windows 10"; break; default: oss = "Linux"; break; } return new MySubBean(oss); } }
MyBean.java
package com.example.vaadincontainer; import java.io.Serializable; public class MyBean implements Serializable { private static final long serialVersionUID = 1L; private String name; private String surname; private MySubBean osUsed; public MyBean (String pname, String psurname, MySubBean pSubBean){ this.name = pname; this.surname = psurname; this.osUsed = pSubBean; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public MySubBean getOsUsed() { return osUsed; } public void setOsUsed(MySubBean osUsed) { this.osUsed = osUsed; } }
MySubBean.java
package com.example.vaadincontainer; import java.io.Serializable; public class MySubBean implements Serializable { private static final long serialVersionUID = 1L; private String os; public MySubBean(String pOs){ this.os = pOs; } public String getOs() { return os; } public void setOs(String os) { this.os = os; } }
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
When you first run the example you only get the harcoded sample data:
Trying to add empty data:
When you add a duplicate surname a Notification is showed:
When you try to add a duplicate name, it’s not added because name is the primary ID and the container ensures unicity of the primary ID:
9. Download the Source Code
This was an example of: Vaadin Container.