Vaadin

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.

01 New Project
01 New Project

Now from the list choose Vaadin 7 project.

02 Vaadin Project
02 Vaadin 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:

03 Sample Data
03 Sample Data

Trying to add empty data:

04 No Data
04 No Data

When you add a duplicate surname a Notification is showed:

05 Duplicate Surname
05 Duplicate Surname

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:

06 Duplicate Name
06 Duplicate Name

9. Download the Source Code

This was an example of: Vaadin Container.

Download
You can download the Eclipse project here: VaadinContainer

Jesus Boadas

I'm a self taught programmer, I began programming back in 1991 using an IBM A10 mainframe with Pascal an Assembler IBM 360/70 emulator and Turbo C on a X86 PC, since that I work for the banking industry with emerging technologies like Fox Pro, Visual Fox Pro, Visual Basic, Visual C++, Borland C++, lately I moved out to the Airline industry, leading designing and programming in-house web applications with Flex, Actionscript, PHP, Python and Rails and in the last 7 years I focused all my work in Java, working on Linux servers using GlassFish, TomCat, Apache and MySql.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button