1. Overview

Vaadin is a server-side Java framework for creating web user interfaces. Using it, we can create our front-end using Java features.

2. Maven Dependencies and Setup

Let’s start by adding the following dependencies to our pom.xml:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-server</artifactId>
</dependency>
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-client-compiled</artifactId>
</dependency>
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-themes</artifactId>
</dependency>

The latest versions of the dependencies can be found here: vaadin-server, vaadin-client-compiled, vaadin-themes.

  • vaadin-server package – includes classes for handling all server details such as sessions, client communication, etc.
  • vaadin-client-compiled – is based on GWT and includes necessary packages to compile the client
  • vaadin-themes – includes some pre-made themes and all utilities for making our themes

To compile our Vaadin widgets, we need to configure the maven-war-plugin, vaadin-maven-plugin, and the maven-clean-plugin. For the full pom, make sure to check the pom file in the source code – at the end of the tutorial.

Also, we also need to add the Vaadin repository and the dependency management:

<repositories>
    <repository>
        <id>vaadin-addons</id>
        <url>http://maven.vaadin.com/vaadin-addons</url>
    </repository>
</repositories>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-bom</artifactId>
            <version>13.0.9</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

The DependencyManagement tag controls versions of all Vaadin dependencies.

To quickly run the application, we’ll use the Jetty plugin:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.3.9.v20160517</version>
    <configuration>
        <scanIntervalSeconds>2</scanIntervalSeconds>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

The latest version of the plugin can be found here: jetty-maven-plugin.

With this plugin we can run our project using the command:

mvn jetty:run

3. What Is Vaadin?

Simply put, Vaadin is a Java framework for creating user interfaces, with themes and components, and a lot of extensibility options.

The framework does cover the server side as well, which means that every change you make to the user interface is immediately sent to the server – so in every moment the backend application knows what is happening in the front-end.

Vaadin consists of a Client and Server side – with the client side built on top of the well-known Google Widget Toolkit framework, and the server side handled by the VaadinServlet.

4. The Servlet

Usually, a Vaadin application doesn’t use a web.xml file; instead, it defines its servlet using annotations:

@WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {}

In this case, this servlet is serving content from the /VAADIN path.

5. The Main Class

The VaadinUI class that is referenced in the servlet must extend the UI class from the framework and must override the init method to complete the bootstrapping of the application with Vaadin enabled.

The next step is to create a layout and add it to a main layout of the application:

public class VaadinUI extends UI {

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout verticalLayout = new VerticalLayout();
        verticalLayout.setSpacing(true);
        verticalLayout.setMargin(true);
        setContent(verticalLayout);
}

6. Vaadin Layout Managers

The framework comes with a number of predefined layout managers.

6.1. VerticalLayout

Stack the components on a column where the first added is on the top and the latest is on the bottom:

VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.setSpacing(true);
verticalLayout.setMargin(true);
setContent(verticalLayout);

Note how the properties here are loosely borrowed from typical CSS terminology.

6.2. HorizontalLayout

This layout places each component side by side from left to right is similar to the vertical layout:

HorizontalLayout horizontalLayout = new HorizontalLayout();

6.3. GridLayout

This layout places each widget in a grid, you need to pass as a parameter the columns and the rows of the grid:

GridLayout gridLayout = new GridLayout(3, 2);

6.4. FormLayout

The form layout puts the caption and the component in two different columns and can have optional indicators for required fields:

FormLayout formLayout = new FormLayout();

7. Vaadin Components

Now that the layout is handled, let’s have a look at some of the more common components for constructing our user interface.

7.1. Label

label

The label is, of course, well known as well – and simply used to display text:

Label label = new Label();
label.setId("LabelID");
label.setValue("Label Value");
label.setCaption("Label");
gridLayout.addComponent(label);

After we create the component, notice the critical step of adding it to the layout.

link

The link widget is essentially a basic hyperlink:

Link link = new Link("Baeldung",
  new ExternalResource("http://www.baeldung.com/"));
link.setTargetName("_blank");

Notice how the typical HTML values of an element are all here.

7.3. TextField

textfield

This widget is used to input text:

TextField textField = new TextField();
textField.setIcon(VaadinIcons.USER);

We can further customize the elements; for example, we can quickly add images to the widgets via the setIcon() API.

Also, note that Font Awesome is shipped out of the box with the framework; it’s defined as an Enum, and we can easily make use of it.

7.4. TextArea

textarea

As you’d expect, TextArea is available next to the rest of the traditional HTML elements:

TextArea textArea = new TextArea();

7.5. DateField and InlineDateField

datefield

This powerful component is used to pick dates; the date parameter is the current date to be selected in the widget:

DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0));

inlinedatefield

We can go further and nest it inside a combo box control to save space:

InlineDateField inlineDateField = new InlineDateField();

7.6. PasswordField

passwordfield

This is the standard masked password input:

PasswordField passwordField = new PasswordField();

7.7. RichTextArea

richtextarea

With this component, we can show formatted text, and it provides an interface to manipulate such text with buttons to control the fonts, size, alignment, etc.are:

RichTextArea richTextArea = new RichTextArea();
richTextArea.setCaption("Rich Text Area");
richTextArea.setValue("<h1>RichTextArea</h1>");
richTextArea.setSizeFull();
Panel richTextPanel = new Panel();
richTextPanel.setContent(richTextArea);

7.8. Button

buttons

Buttons are used for capturing user input and come in a variety of sizes and colors.

To create a button we instantiate the widget class as usual:

Button normalButton = new Button("Normal Button");

Changing the style we can have some different buttons:

tinyButton.addStyleName("tiny");
smallButton.addStyleName("small");
largeButton.addStyleName("large");
hugeButton.addStyleName("huge");
dangerButton.addStyleName("danger");
friendlyButton.addStyleName("friendly");
primaryButton.addStyleName("primary");
borderlessButton.addStyleName("borderless");
linkButton.addStyleName("link");
quietButton.addStyleName("quiet");

We can create a disabled button:

Button disabledButton = new Button("Disabled Button");
disabledButton.setDescription("This button cannot be clicked");
disabledButton.setEnabled(false);
buttonLayout.addComponent(disabledButton);

A native button that uses the browser’s look:

NativeButton nativeButton = new NativeButton("Native Button");
buttonLayout.addComponent(nativeButton);

And a button with an icon:

Button iconButton = new Button("Icon Button");
iconButton.setIcon(VaadinIcons.ALIGN_LEFT);
buttonLayout.addComponent(iconButton);

7.9. CheckBox

checkbox

The check box is a change state element, is checked or is unchecked:

CheckBox checkbox = new CheckBox("CheckBox");        
checkbox.setValue(true);
checkbox.addValueChangeListener(e ->
  checkbox.setValue(!checkbox.getValue()));
formLayout.addComponent(checkbox);

7.10. Lists

Vaadin has some useful widgets to handle lists.

First, we create a list of our items to be placed in the widget:

List<String> numbers = new ArrayList<>();
numbers.add("One");
numbers.add("Ten");
numbers.add("Eleven");

The ComboBox is a drop down list:

combobox

ComboBox comboBox = new ComboBox("ComboBox");
comboBox.addItems(numbers);
formLayout.addComponent(comboBox);

The ListSelect vertically places items and uses a scroll bar in case of overflow:

listselect

ListSelect listSelect = new ListSelect("ListSelect");
listSelect.addItems(numbers);
listSelect.setRows(2);
formLayout.addComponent(listSelect);

The NativeSelect is like the ComboBox but have the browser look and feel:

nativeselect

NativeSelect nativeSelect = new NativeSelect("NativeSelect");
nativeSelect.addItems(numbers);
formLayout.addComponent(nativeSelect);

The TwinColSelect is a dual list where we can change the items between these two panes; each item can only live in one of the panes at a time:

twincolselect

TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
twinColSelect.addItems(numbers);

7.11. Grid

The grid is used to show data in a rectangular way; you have rows and columns, can define header and foot for the data:

grid

Grid<Row> grid = new Grid(Row.class);
grid.setColumns("column1", "column2", "column3");
Row row1 = new Row("Item1", "Item2", "Item3");
Row row2 = new Row("Item4", "Item5", "Item6");
List<Row> rows = new ArrayList();
rows.add(row1);
rows.add(row2);
grid.setItems(rows);

The Row class above is a simple POJO we’ve added to represent a row:

public class Row {
    private String column1;
    private String column2;
    private String column3;

    // constructors, getters, setters
}

8. Server Push

Another interesting feature is an ability to send messages from the server to the UI.

To use server push, we need to add the following dependency to our pom.xml:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-push</artifactId>
    <versionId>8.8.5</versionId>
</dependency>

The latest version of the dependency can be found here: vaadin-push.

Also, we need to add the @Push annotation to our class representing UI:

@Push
@Theme("mytheme")
public class VaadinUI extends UI {...}

We create a label to capture the server push message:

private Label currentTime;

We then create a ScheduledExecutorService that sends the time from the server to the label:

ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
    currentTime.setValue("Current Time : " + Instant.now());
};
scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);

The ScheduledExecutorService is running on the server side of the application and every time it runs, the user interface gets updated.

9. Data Binding

We can bind our user interface to our business classes.

First, we create a Java class:

public class BindData {

    private String bindName;

    public BindData(String bindName){
        this.bindName = bindName;
    }
    
    // getter & setter
}

Then we bind our class that has a single field to a TextField in our user interface:

Binder<BindData> binder = new Binder<>();
BindData bindData = new BindData("BindData");
binder.readBean(bindData);
TextField bindedTextField = new TextField();
binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName);

First, we create a BindData object using the class we created before, then the Binder binds the field to the TextField.

10. Validators

We can create Validators to validate the data in our input fields. To do that, we attach the validator to the field we want to validate:

BindData stringValidatorBindData = new BindData("");
TextField stringValidator = new TextField();
Binder<BindData> stringValidatorBinder = new Binder<>();
stringValidatorBinder.setBean(stringValidatorBindData);
stringValidatorBinder.forField(stringValidator)
  .withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5))
  .bind(BindData::getBindName, BindData::setBindName);

Then we validate our data before we use it:

Button buttonStringValidator = new Button("Validate String");
buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate());

In this case, we are using the StringLengthValidator that validates the length of a String but Vaadin provides other useful validators and also allows us to create our custom validators.

11. Summary

Of course, this quick writeup barely scratched the surface; the framework is much more than user interface widgets, Vaadin provides all you need for creating modern web applications using Java.

And, as always, the code can be found over on Github.