Vaadin Example Application
An application is a computer program created to perform a group of useful tasks for an end user. Application could be a vast topic to cover, just because a simple “Hello World” program is an application. Most applications do much more than only print a hello message on the user interface.
The “Hello world” application is useful as an initial program when you are learning a new programming language to illustrate the basic syntax for constructing a working program and get it to run on a computer. The first “Hello World” application was created by Brian Kernigham in a internal memorandum of Bell Laboratories “Programming in C a tutorial”.
1. The tools
- Java JDK 8
- Latest Eclipse Mars
- Vaadin 7.6.6
- Tomcat Server 8
2. Introduction
In this example we are going to create a sample Vaadin application to show common widgets interacting with each other. We generate a character sheet for an RPG game using random values. If the values appeal to us, we could save them for later use. This application could be useful to you if you play tabletop RPG games but further than that, is an application to illustrate some common Vaadin widgets working together.
3. Prerequisites
- JDK installed
- Eclipse Mars installed and working
- Vaadin plug-in 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
Class variables
private Table attr; private Table savedAttr; private Item str; private Item con; private Item nte; private Item agi; private Item wis; private Random rnd;
We declared two tables and five items to manage our data, also a random instance to generate random numbers.
Layouts
final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout); HorizontalLayout topHorLay = new HorizontalLayout(); topHorLay.setSizeFull(); topHorLay.setSpacing(true); VerticalLayout butLay = new VerticalLayout(); butLay.setSizeFull(); butLay.setSpacing(true); Label butLabel = new Label("Is this OK?"); butLabel.setStyleName("h2");
We create the layouts, a main vertical layout, a horizontal layout for the first row of the main layout and a vertical layout to place the buttons of the application.
CellStyleGenerator
CellStyleGenerator myCellColors = new CellStyleGenerator() { @Override public String getStyle(Table source, Object itemId, Object propertyId) { if(propertyId!=null){ Item item = source.getItem(itemId); if(item.getItemProperty(propertyId).getValue().getClass()==Integer.class){ Integer cellValue = (Integer)item.getItemProperty(propertyId).getValue(); if(cellValue > 15 && cellValue 17){ return "green"; } if(cellValue < 8){ return "red"; } } } return null; } };
This CellStyleGenerator
changes the color of individual cells based on it’s value. First we check that the cell is no empty with if(propertyId!=null)
. Then we get the Item
in the cell with Item item = source.getItem(itemId);
.
We then Check the value of the Item
and verify that is an integer with if(item.getItemProperty(propertyId).getValue().getClass()==Integer.class)
.
If the value is an Integer, we cast it to a local variable with Integer cellValue = (Integer)item.getItemProperty(propertyId).getValue();
and based on the value of the variable we set the colors of the cells in the table.
Attributes Table
attr = new Table("Attributes"); attr.addContainerProperty("Attribute", String.class, null); attr.addContainerProperty("Value", Integer.class, 0); attr.setPageLength(attr.size()); attr.setSelectable(false); attr.setImmediate(true); attr.setFooterVisible(false); attr.setCellStyleGenerator(myCellColors);
This table is going to have the generated values, one string column with the name of the attribute and an integer column holding the value of that attribute. We create the table with attr = new Table("Attributes");.
attr
is a class field. attr.addContainerProperty("Attribute", String.class, null);
defines the first value data type as string.
attr.addContainerProperty("Value", Integer.class, 0);
defines the second column data type as integer. With attr.setPageLength(attr.size());
we constrain the size of the table on the screen to the size of the data contained on it.
attr.setSelectable(false);
, the user cannot select the rows on the table.attr.setImmediate(true);
set immediate tells the application to send any changes on the table to the server, when they occur. Hide the footer of the table attr.setFooterVisible(false);
.
And tell the table to use our custom cell style generator attr.setCellStyleGenerator(myCellColors);
.
Helper initialization
rnd = new Random(); createCharacterTable();
rnd = new Random();
initializes the random number generator. createCharacterTable();
, calls a custom method to fill the table with the initial values. This is explained later on this article.
Table of saved attributes
savedAttr = new Table("Saved Rolls"); savedAttr.setSizeFull(); savedAttr.addContainerProperty("Name", String.class, ""); savedAttr.addContainerProperty("Strength", Integer.class, 0); savedAttr.addContainerProperty("Constitution", Integer.class, 0); savedAttr.addContainerProperty("Intelligence", Integer.class, 0); savedAttr.addContainerProperty("Agility", Integer.class, 0); savedAttr.addContainerProperty("Wisdom", Integer.class, 0); savedAttr.setCellStyleGenerator(myCellColors);
This table is going to have the saved data of our application.savedAttr = new Table("Saved Rolls");
creates the table.savedAttr.setSizeFull();
sets the size of the table to fit all the space available.
savedAttr.addContainerProperty("Name", String.class, "");
, adds a string column to hold the name of our character.savedAttr.addContainerProperty("Strenght", Integer.class, 0);
adds an integer column to hold the strength attribute.savedAttr.addContainerProperty("Constitution", Integer.class, 0);
, adds an integer column to hold the constitution attribute.savedAttr.addContainerProperty("Intelligence", Integer.class, 0);
, adds an integer column to hold the intelligence attribute.savedAttr.addContainerProperty("Agility", Integer.class, 0);
adds an integer column to hold the agility attribute.savedAttr.addContainerProperty("Wisdom", Integer.class, 0);
adds the column of the wisdom attribute.savedAttr.setCellStyleGenerator(myCellColors);
attachs the custom cell styles to the table.
Button reroll
Button reroll = new Button("Reroll"); reroll.setWidth("200px"); reroll.setIcon(FontAwesome.DIAMOND); reroll.addStyleName("friendly"); reroll.addClickListener(new ClickListener() { @SuppressWarnings("unchecked") @Override public void buttonClick(ClickEvent event) { str.getItemProperty("Value").setValue(getReroll()); con.getItemProperty("Value").setValue(getReroll()); nte.getItemProperty("Value").setValue(getReroll()); agi.getItemProperty("Value").setValue(getReroll()); wis.getItemProperty("Value").setValue(getReroll()); } });
With this button we randomize all attributes with new values. Button reroll = new Button("Reroll");
creates the button. reroll.setWidth("200px");
sets the width of the button to “200px”. reroll.setIcon(FontAwesome.DIAMOND);
assigns an icon to the button using fontawesome that is shipped with Vaadin out of the box.
reroll.addStyleName("friendly");
adds the Vaadin friendly style to the button, this style is predefined in Vaadin. reroll.addClickListener(new ClickListener()
adds the listener to the button, inside the listener we call str.getItemProperty("Value").setValue(getReroll());
to get a new strength value using getReroll()
method that is explained later.
The same procedure is done with all attributes in the table to get new random values.
Name TextField
TextField name = new TextField("Character Name"); name.setRequired(true); name.setWidth("200px");
With TextField name = new TextField("Character Name");
we create the text field to input the name of the character. name.setRequired(true);
sets the field required. name.setWidth("200px");
sets the width of the field the same as the buttons.
Button save
Button save = new Button("Save"); save.addStyleName("primary"); save.setIcon(FontAwesome.SAVE); save.setWidth("200px"); save.addClickListener(new ClickListener()
Create a new button with Button save = new Button("Save");
. save.addStyleName("primary");
assigns style primary to the button. save.setIcon(FontAwesome.SAVE);
sets an icon for font awesome.
save.setWidth("200px");
sets the width to the button to 200 pixels.
save.addClickListener(new ClickListener()
adds a click listener to the button.
Save click listener
public void buttonClick(ClickEvent event) { int istr = (int) str.getItemProperty("Value").getValue(); int icon = (int) con.getItemProperty("Value").getValue(); int inte = (int) nte.getItemProperty("Value").getValue(); int iagi = (int) agi.getItemProperty("Value").getValue(); int iwis = (int) wis.getItemProperty("Value").getValue(); if((istr != 0) && (icon != 0) && (inte != 0) && (iagi != 0) && (iwis != 0)){ if(name.isEmpty()){ Notification.show("The name is required"); }else{ String cName = name.getValue(); if(findDuplicates(cName)){ Notification.show("Name is duplicated"); }else{ Object savedAttrId = savedAttr.addItem(); Item nSavAttr = savedAttr.getItem(savedAttrId); nSavAttr.getItemProperty("Name").setValue(cName); nSavAttr.getItemProperty("Strenght").setValue(istr); nSavAttr.getItemProperty("Constitution").setValue(icon); nSavAttr.getItemProperty("Intelligence").setValue(inte); nSavAttr.getItemProperty("Agility").setValue(iagi); nSavAttr.getItemProperty("Wisdom").setValue(iwis); name.setValue(""); Notification.show("Character saved!"); } } }else{ Notification.show("You must generate a character first"); } }
When the save button is clicked the click listener is called by the framework. int istr = (int) str.getItemProperty("Value").getValue();
gets the value of strength and cast it to an integer. int icon = (int) con.getItemProperty("Value").getValue();
gets the value of constitution and cast it to an integer. int icon = (int) nte.getItemProperty("Value").getValue();
gets the value of intelligence and cast it to an integer.
int inte = (int) agi.getItemProperty("Value").getValue();
gets the value of agility and cast it to an integer. int iwis = (int) wis.getItemProperty("Value").getValue();
gets the value of wisdom and cast it to an integer.
if((istr != 0) && (icon != 0) && (inte != 0) && (iagi != 0) && (iwis != 0))
checks the values has been generated.
Otherwise a notification is send to the user. name.isEmpty()
checks the name is no empty. If the name is empty a notification is triggered.String cName = name.getValue()
gets the name into a string variable. findDuplicates(cName)
check if the name is already used.
When all conditions are meet then we proceed to save the character into the saved rolls table. Object savedAttrId = savedAttr.addItem();
creates a new object from the saved attributes table. Item nSavAttr = savedAttr.getItem(savedAttrId);
gets the item from the container.
nSavAttr.getItemProperty("Name").setValue(cName);
sets the value of the name into the saved attribute container, also we set all other properties from the container with the values we already have.
nSavAttr.getItemProperty("Strenght").setValue(istr);
sets the strength. nSavAttr.getItemProperty("Constitution").setValue(icon);
sets the constitution.
nSavAttr.getItemProperty("Intelligence").setValue(inte);
sets the intelligence. nSavAttr.getItemProperty("Agility").setValue(iagi);
sets the agility. nSavAttr.getItemProperty("Wisdom").setValue(iwis);
.
Now we set the name text field to an empty string and send a notification to the user indicating that the character has been saved.
Add the widgets to the layouts
butLay.addComponent(butLabel); butLay.addComponent(reroll); butLay.addComponent(save); butLay.addComponent(name); topHorLay.addComponent(attr); topHorLay.addComponent(butLay); layout.addComponent(topHorLay); layout.addComponent(savedAttr);
We add the buttons to the vertical butLay
layout and then we add the attr
table and the butLay
to the horizontal topHorLay
layout. Finally we add the topHorLay
layout and the savedAttr
table to the main layout.
createCharacterTable method
private void createCharacterTable() { Object strItemId = attr.addItem(); str = attr.getItem(strItemId); str.getItemProperty("Attribute").setValue("STR"); str.getItemProperty("Value").setValue(0); Object conItemId = attr.addItem(); con = attr.getItem(conItemId); con.getItemProperty("Attribute").setValue("CON"); con.getItemProperty("Value").setValue(0); Object nteItemId = attr.addItem(); nte = attr.getItem(nteItemId); nte.getItemProperty("Attribute").setValue("INT"); nte.getItemProperty("Value").setValue(0); Object agiItemId = attr.addItem(); agi = attr.getItem(agiItemId); agi.getItemProperty("Attribute").setValue("AGI"); agi.getItemProperty("Value").setValue(0); Object wisItemId = attr.addItem(); wis = attr.getItem(wisItemId); wis.getItemProperty("Attribute").setValue("WIS"); wis.getItemProperty("Value").setValue(0); }
This method populate the attr
table with two columns attribute and value and each row is an attribute used.
getReroll method
private int getReroll(){ return rnd.nextInt(19)+1; }
This method generates random integers to get the values of the attributes.
findDuplicates method
private boolean findDuplicates(String newName){ for(Iterator i = savedAttr.getItemIds().iterator(); i.hasNext();){ int iid = (Integer) i.next(); Item item = savedAttr.getItem(iid); String curName = (String) item.getItemProperty("Name").getValue(); if(newName.toLowerCase().equals(curName.toLowerCase())){ return true; } } return false; }
This method returns true if a name already exist in the saved attributes table.
6. The complete source code
VaadinappexampleUI.java
package com.example.vaadinappexample; import javax.servlet.annotation.WebServlet; import java.util.Iterator; import java.util.Random; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.data.Item; import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.Table.CellStyleGenerator; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; @SuppressWarnings("serial") @Theme("vaadinappexample") public class VaadinappexampleUI extends UI { @WebServlet(value = "/*", asyncSupported = true) @VaadinServletConfiguration(productionMode = false, ui = VaadinappexampleUI.class, widgetset = "com.example.vaadinappexample.widgetset.VaadinappexampleWidgetset") public static class Servlet extends VaadinServlet { } private Table attr; private Table savedAttr; private Item str; private Item con; private Item nte; private Item agi; private Item wis; private Random rnd; @Override protected void init(VaadinRequest request) { final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout); HorizontalLayout topHorLay = new HorizontalLayout(); topHorLay.setSizeFull(); topHorLay.setSpacing(true); VerticalLayout butLay = new VerticalLayout(); butLay.setSizeFull(); butLay.setSpacing(true); Label butLabel = new Label("Is this OK?"); butLabel.setStyleName("h2"); CellStyleGenerator myCellColors = new CellStyleGenerator() { @Override public String getStyle(Table source, Object itemId, Object propertyId) { if(propertyId!=null){ Item item = source.getItem(itemId); if(item.getItemProperty(propertyId).getValue().getClass()==Integer.class){ Integer cellValue = (Integer)item.getItemProperty(propertyId).getValue(); if(cellValue > 15 && cellValue 17){ return "green"; } if(cellValue < 8){ return "red"; } } } return null; } }; attr = new Table("Attributes"); attr.addContainerProperty("Attribute", String.class, null); attr.addContainerProperty("Value", Integer.class, 0); attr.setPageLength(attr.size()); attr.setSelectable(false); attr.setImmediate(true); attr.setFooterVisible(false); attr.setCellStyleGenerator(myCellColors); rnd = new Random(); createCharacterTable(); savedAttr = new Table("Saved Rolls"); savedAttr.setSizeFull(); savedAttr.addContainerProperty("Name", String.class, ""); savedAttr.addContainerProperty("Strength", Integer.class, 0); savedAttr.addContainerProperty("Constitution", Integer.class, 0); savedAttr.addContainerProperty("Intelligence", Integer.class, 0); savedAttr.addContainerProperty("Agility", Integer.class, 0); savedAttr.addContainerProperty("Wisdom", Integer.class, 0); savedAttr.setCellStyleGenerator(myCellColors); Button reroll = new Button("Reroll"); reroll.setWidth("200px"); reroll.setIcon(FontAwesome.DIAMOND); reroll.addStyleName("friendly"); reroll.addClickListener(new ClickListener() { @SuppressWarnings("unchecked") @Override public void buttonClick(ClickEvent event) { str.getItemProperty("Value").setValue(getReroll()); con.getItemProperty("Value").setValue(getReroll()); nte.getItemProperty("Value").setValue(getReroll()); agi.getItemProperty("Value").setValue(getReroll()); wis.getItemProperty("Value").setValue(getReroll()); } }); TextField name = new TextField("Character Name"); name.setRequired(true); name.setWidth("200px"); Button save = new Button("Save"); save.addStyleName("primary"); save.setIcon(FontAwesome.SAVE); save.setWidth("200px"); save.addClickListener(new ClickListener() { @SuppressWarnings("unchecked") @Override public void buttonClick(ClickEvent event) { int istr = (int) str.getItemProperty("Value").getValue(); int icon = (int) con.getItemProperty("Value").getValue(); int inte = (int) nte.getItemProperty("Value").getValue(); int iagi = (int) agi.getItemProperty("Value").getValue(); int iwis = (int) wis.getItemProperty("Value").getValue(); if((istr != 0) && (icon != 0) && (inte != 0) && (iagi != 0) && (iwis != 0)){ if(name.isEmpty()){ Notification.show("The name is required"); }else{ String cName = name.getValue(); if(findDuplicates(cName)){ Notification.show("Name is duplicated"); }else{ Object savedAttrId = savedAttr.addItem(); Item nSavAttr = savedAttr.getItem(savedAttrId); nSavAttr.getItemProperty("Name").setValue(cName); nSavAttr.getItemProperty("Strenght").setValue(istr); nSavAttr.getItemProperty("Constitution").setValue(icon); nSavAttr.getItemProperty("Intelligence").setValue(inte); nSavAttr.getItemProperty("Agility").setValue(iagi); nSavAttr.getItemProperty("Wisdom").setValue(iwis); name.setValue(""); Notification.show("Character saved!"); } } }else{ Notification.show("You must generate a character first"); } } }); butLay.addComponent(butLabel); butLay.addComponent(reroll); butLay.addComponent(save); butLay.addComponent(name); topHorLay.addComponent(attr); topHorLay.addComponent(butLay); layout.addComponent(topHorLay); layout.addComponent(savedAttr); } @SuppressWarnings("unchecked") private void createCharacterTable() { Object strItemId = attr.addItem(); str = attr.getItem(strItemId); str.getItemProperty("Attribute").setValue("STR"); str.getItemProperty("Value").setValue(0); Object conItemId = attr.addItem(); con = attr.getItem(conItemId); con.getItemProperty("Attribute").setValue("CON"); con.getItemProperty("Value").setValue(0); Object nteItemId = attr.addItem(); nte = attr.getItem(nteItemId); nte.getItemProperty("Attribute").setValue("INT"); nte.getItemProperty("Value").setValue(0); Object agiItemId = attr.addItem(); agi = attr.getItem(agiItemId); agi.getItemProperty("Attribute").setValue("AGI"); agi.getItemProperty("Value").setValue(0); Object wisItemId = attr.addItem(); wis = attr.getItem(wisItemId); wis.getItemProperty("Attribute").setValue("WIS"); wis.getItemProperty("Value").setValue(0); } private int getReroll(){ return rnd.nextInt(19)+1; } private boolean findDuplicates(String newName){ for(Iterator i = savedAttr.getItemIds().iterator(); i.hasNext();){ int iid = (Integer) i.next(); Item item = savedAttr.getItem(iid); String curName = (String) item.getItemProperty("Name").getValue(); if(newName.toLowerCase().equals(curName.toLowerCase())){ return true; } } return false; } }
vaadinappexample.scss
@import "../valo/valo.scss"; @mixin vaadinappexample { @include valo; .v-table-cell-content-green { background: #33BB00; color: #FFFFFF; } .v-table-cell-content-orange { background: #FCB724; color: #FFFFFF; } .v-table-cell-content-red { background: #FF0000; color: #FFFFFF; } }
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
9. Download the Source Code
This was an example of: Vaadin Application.