Docs

Documentation versions (currently viewingVaadin 8)

Vaadin 8 reached End of Life on February 21, 2022. Discover how to make your Vaadin 8 app futureproof →

Vaadin 8 Tutorial

Warning
Vaadin 8 reached End of Life
If you are just starting with Vaadin, go instead to the quick-start tutorial of the latest stable version.

This tutorial gives you an overview of how you can use the Vaadin 8 Framework to build single-page web UIs for your Java application. All you need to start with it is JDK 8 and an IDE, such as Eclipse. While this tutorial is written for Eclipse users, you can use your IDE of choice. No extensive knowledge of Java is needed, only basic programming skills are required.

1. Overview

You’ll have your first Vaadin app running in your IDE in a couple of minutes. To complete the whole tutorial, you’ll need about 20 to 60 minutes, depending on your existing experience. Naturally, you can just do the beginning of the exercise or pick any of the steps you want. To start from a specific step, we have prepared the example code after each step to be downloaded as a zip file.

Tip
The free training videos are an accessible way to get familiar with Vaadin 8. See all courses here!

In this tutorial, we build a simple customer management system. It is not a real application; we use an in-memory "back-end", so that you can understand how to hook it to an existing Java based back-end. We cover the basic Vaadin development and you can use the result as a basis for more experiments with Vaadin, such as using add-ons, your own custom look-and- feel (aka. theme), adding new views, or optimizing the result for mobile support.

finalUI
UI to be built in the tutorial

If you do not want to do the exercise at all, you can also just download the final application and play around with it.

Tip
In addition to this written tutorial, we have recorded the steps as a series of videos. You can just watch all the videos or watch the video of each step before you do the same step yourself.

1.1. Installing the Development Tools

The tutorial uses Java 8, so please ensure that you have an up-to-date JDK 8 installed. Most Linux distributions can use package managers to install JDK8. Windows and Mac users should download it from Oracle’s Java SE site.

Also make sure you have the latest version of your IDE. Eclipse is available in various packages; be sure to download the Eclipse IDE for Java EE Developers from eclipse.org.

2. Creating a Project from an Archetype

The following video shows how to do this step of the tutorial:

As the starting point for the application, we use a Maven archetype called vaadin-archetype-application. Archetypes are project stubs that have some example code and a basic Maven build script.

  1. Start by choosing File  New  Maven Project from the menu.

    createMavenProject
    Create a new Maven project
    Tip
    If the Maven Project is not visible in the menu, you should switch to the Java EE perspective. You can use the shortcut button in the tool bar or Window  Perspective to switch to the perspective.
  2. The first step in the wizard is good as is for our purpose. Just click Next.

  3. In the second step, you need to choose the vaadin-archetype-application archetype.

    projectWizard2 top
    Selecting the archetype

    You can first try to find it using the filtering function.

    If Eclipse has not yet indexed the archetype catalog, you need to manually add the archetype details.

    Tip
    Some Eclipse installations do not automatically add Maven Central to the list of Maven catalogues, resulting in the Vaadin archetypes not being available in the wizard. To fix this, open Eclipse Preferences > Maven > Archetypes and select Add Remote Catalog. The URL to the Maven Central catalog file is http://repo1.maven.org/maven2/archetype-catalog.xml. After applying the changes, the Vaadin archetypes should be available in the wizard.

    Click the Add Archetype button.

    projectWizardAddArchetype crop
    Settings for a new archetype

    Enter the following values:

    Group ID

    Give com.vaadin

    Artifact ID

    Give vaadin-archetype-application

    Version

    You can find the latest Vaadin version number from vaadin.com/framework/releases.

    Repository URL

    This can be left blank.

    And click OK. Now you can select the new archetype from the list.

    Warning
    Eclipse has a bug in its project wizard. The vaadin-archetype-application may not appear in the listing, even though you added it using the Add Archetype button. If this occurs, close the whole new project wizard and re-open it by selecting File  New  Maven Project again. The archetype then typically appears in the listing and can be found by the filtering functionality.
  4. In the next wizard step, type in the following fields:

    Group Id

    my.vaadin

    Artifact Id

    app

    and click Finish.

If this is your first Vaadin app, creating a project might take a while, depending on the speed of your network, as Vaadin libraries and other dependencies are being downloaded. Maven caches them on your local file system. Creating your next Maven-based Vaadin project will be much faster.

Right click on the newly created project and choose Run as  Maven Install. This initiates a full build of your application and finally creates a WAR file into the target directory. You can deploy the WAR file to your application server. The first build might take a while, as Maven might again need to download some new modules.

Tip
For the Maven compilation to work you need a JDK to be configured in your Eclipse in Window  Preferences  Java  Installed JREs  Add…​. This step is necessary at least on Windows, if you are using a fresh installation of Eclipse or for some other reason haven’t configured a JDK to your Eclipse. The JDK by default installs to \Program Files\Java on Windows. You can make JDK the default JRE for your Eclipse.

While the build is running, let us have a look at what the archetype created for you. You can browse your project resources from the tree structure in the Project Explorer. Maven’s pom.xml on top level contains settings for building your project and declares the used dependencies. Open Java Resources and below it src/main/java, the main source directory, and my.vaadin.app, the main Java package that will contain your Vaadin UI code.

Tip
Eclipse shows all project files in the Project Explorer. In this case, you can also find your .java files from under the top-level src node. However, the suggested method is to access them from under the Java Resources node, which is optimized for editing Java source code.

The UI code (and the Servlet declaration) used by the application stub can be found in the MyUI.java file. Let us read it through to see how it works. The init() method of a UI class is triggered when a user enters your web application. The VerticalLayout is one of the most used layout components, which are used to position and display other Vaadin components in your UI classes. The example code creates one TextField to allow the user to input her name and a Button whose click listener dynamically adds a new Label component to the main layout. In the end of the init() method, we just configure the main layout and place components into it and set it to be the content of MyUI.

To test your first Vaadin application, right-click on the project and choose Debug as  Maven build…​. The debug mode is slightly slower than the basic run mode, but it often helps you to figure out what is happening in your application.

debugAsMavenBuild
Starting the server using a Maven target

In the dialog, type Run in jetty to the Name input and jetty:run to the Goals input.

debugAsMavenBuild2
Generating a Maven launch for jetty:run target

Before clicking debug, to make sure debugging works properly, add your Java project to the source lookup path from the Source tab, as it is being done in Adding sources for debugging.

debugAsMavenBuildAddSources
Adding sources for debugging

Now click Debug to continue. This will download a small Java web server (if not cached to your local Maven repository), and use it to host your application. Once the server has started, point your browser to the URL http://localhost:8080/ to see the running application.

If you make changes to the code, the Jetty server will notice the changes and in a couple of seconds most changes are automatically deployed. Reloading the page in your browser will show the changes.

Tip
In some cases your JVM might not allow injecting changes on the fly. In these cases, Eclipse will complain about "Hot code replacement error". Just choose to restart the server to get the latest changes. Many Java developers use a commercial tool called JRebel to make code replacement work better.

Mastering the usage of the Java debugger is also handy to better understand how your application actually works and fixing bugs that all developers write at some point. As Vaadin is "only" Java code, you can use all of Java’s debugging tools, which cannot be done with other UI frameworks where the UI is written (partly) in HTML and/or JavaScript. Double-click on the line number in the Java editor, for example of the following line in the click listener:

layout.addComponent(new Label("Thanks " + name.getValue()));

Doing so adds a breakpoint to the selected line. If you then click the button in your browser, the execution of the application will stop on that line. Eclipse will ask you to enter to Debugging perspective. That way you can step through the execution and inspect the variables. Clicking on the play icon in the toolbar will continue the execution. Double-click the same line again to remove the breakpoint.

debugInBreakPointVariable
Execution in a break point in the button click listener

Clicking the red square in the Console view will terminate the server process. You can restart it easily form the run/debug history. You can find that from the small down arrow next to the green play button or bug button (for the debug mode) in the tool bar. Alternatively, you can use the main menu Run  Run history/Debug history  Run in Jetty.

To get back to the Java EE Perspective, an Eclipse mode designed for editing Java web app code, click the Java EE button in the toolbar.

3. Adding a demo "backend"

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

Before getting more into real Vaadin development, let us introduce some domain objects and a "fake backend". In a real-world application, you will most likely have something similar, implemented with, for example, JPA and EJB or a Spring-based service.

The following video shows how to do this step of the tutorial:

Copy the following three classes from github to your project. Class names point to the classes hosted in Github. Copying classes can be done in many ways.

Tip
The fastest way to copy classes using Eclipse is to use your good old clipboard. Select the text content of the whole class from your browser, choose Edit  Copy, focus the node representing the my.vaadin.app Java package in Eclipse’s Java Resources view and choose Edit  Paste. Eclipse is smart enough to automatically create a properly named Java file for the class.
  • CustomerStatus - this is a simple enum class

  • Customer - this is the main domain object, a basic Java bean that we will be using in our example

  • CustomerService - this is a simple facade via which you can request and modify Customer instances. You can think of this as your entry point to your fake database.

In the next steps, we will be using these classes and build a UI around them. The actual implementation of these classes is not relevant for this tutorial, but feel free to have a look around.

4. Listing entities in a Grid

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

Often when you start building a UI for a data-centric application, the first thing you want to do is to list your data from your back-end. There are several components and ways in Vaadin to do this. In this example, we will use the Grid component for tabular presentation of our customers.

The following video shows how to do this step of the tutorial:

We start by introducing a Grid to the MyUI class. We could of course just introduce the Grid as a variable in the init() method, but we most likely want to refer to it later. Also, let us get a reference to the CustomerService.

public class MyUI extends UI {
    // Add the next two lines:
    private CustomerService service = CustomerService.getInstance();
    private Grid<Customer> grid = new Grid<>(Customer.class);

    // The rest is already there...
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        ...
Tip
If you are new to Java development, you probably do not feel comfortable with the red compilation error for the line where the Grid got introduced, because of a missing import. This is easily fixed in Eclipse by using the Source  Organize Imports command. Learn its shortcut (Ctrl-Shift-O or CMD-Shift-O on Macs), you’ll be using it a lot in Java development. In possible class name collisions, always choose the appropriate class from the com.vaadin.ui package if you want to import core Vaadin UI classes like the Grid.

To simply list all properties of all Customer objects from the backend service, replace the init method with the following snippet:

@Override
protected void init(VaadinRequest vaadinRequest) {
    final VerticalLayout layout = new VerticalLayout();

    // add Grid to the layout
    layout.addComponents(grid);

    // fetch list of Customers from service and assign it to Grid
    List<Customer> customers = service.findAll();
    grid.setItems(customers);

    setContent(layout);
}
Tip
Again, use the organize imports feature. The List object we use here is java.util.List.

As we’ll want to refresh the listing from various places in our application, extract the customer listing part into its own "updateList" method with the public modifier. The public modifier is handy later when we want to update the listing from other classes. You can let Eclipse help here by selecting the relevant lines and using the "quick fix" feature (Ctrl+1 or Cmd+1 on Macs). The extracted method call looks like this:

    public void updateList() {
        List<Customer> customers = service.findAll();
        grid.setItems(customers);
    }

If you try the application now, you’ll see an empty Grid with no columns. To add columns, configure the Grid using the setColumns method to show the "firstName", "lastName" and "email" properties.

    grid.setColumns("firstName", "lastName", "email");

At this point the body of the MyUI class should look like this (servlet declaration omitted):

private CustomerService service = CustomerService.getInstance();
private Grid<Customer> grid = new Grid<>(Customer.class);

@Override
protected void init(VaadinRequest vaadinRequest) {
    final VerticalLayout layout = new VerticalLayout();

    grid.setColumns("firstName", "lastName", "email");

    // add Grid to the layout
    layout.addComponent(grid);

    updateList();

    setContent(layout);
}

public void updateList() {
    // fetch list of Customers from service and assign it to Grid
    List<Customer> customers = service.findAll();
    grid.setItems(customers);
}

You can now save your changes to the file and verify the changes from your browser. You can do this at any point during the rest of the tutorial as well.

5. Creating live filtering for entities

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

A search functionality is expected in every modern application and it is also a nice Vaadin development exercise. Let’s add a filtering functionality to the Customer listing we created in the previous step.

The following video shows how to do this step of the tutorial:

We’ll start by introducing a TextField component as a field to our UI class:

    private TextField filterText = new TextField();

In the init() method, configure the text field to contain a helpful input prompt and add a text change listener to the field. The exact place of these lines is not important, but add them, for example, after you have introduced the layout object.

filterText.setPlaceholder("filter by name...");
filterText.addValueChangeListener(e -> updateList());
filterText.setValueChangeMode(ValueChangeMode.LAZY);
Tip
To keep your code more readable, you can use autoformat after you write or copy paste code snippets. The default keyboard shortcut in Eclipse is Ctrl+Shift+F or Cmd+Shift+F

As its name implies, the value change listener allows you to react to changes in the value contained in the text field. It is configured so that the event is fired lazily while the user is typing, when there is a small pause in the typing. This makes it perfect for this kind of automatic filtering. When the user has changed the text, we’ll just update the listing calling the updateList method.

To keep the updateList method functional, it should take into consideration the possible value in the filterText field. Change the line for fetching the customers into this:

  List<Customer> customers = service.findAll(filterText.getValue());

Before adding the text field to the UI, let’s improve the usability a bit and make a short exercise to compose better components from lower level UI components. The search field can naturally be cleared with the keyboard, but let’s add a clear button next to the text field. Start by adding the following lines to the init method, for example right after your filterText configuration:

Button clearFilterTextBtn = new Button(VaadinIcons.CLOSE);
clearFilterTextBtn.setDescription("Clear the current filter");
clearFilterTextBtn.addClickListener(e -> filterText.clear());

Vaadin contains a set of built in icons, from which we use the "X" icon, VaadinIcons.CLOSE, here, which most users will recognise as a functionality to clear the value. If we set the description to a component, it will be shown as a tooltip for those users who hover the cursor over the button and wonder what to do with it. In the click listener, we simply clear the text from the field.

Vaadin contains lots of different kinds of layouts. The simplest way to align the text field and the button next to each other would be to use a HorizontalLayout. An alternative way we use here is using a CssLayout, which is a lightweight layout that is easy to customize with css. Even if you wouldn’t want to play with CSS yourself, you can often use one of the existing style rules in the default Valo theme. The following snippet will create a nice compact "composition" of both the TextField and the clear button. Add these lines to the init method right after you configured the clearFilterTextBtn:

CssLayout filtering = new CssLayout();
filtering.addComponents(filterText, clearFilterTextBtn);
filtering.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);

Finally, change the line in the init method that currently adds only the grid, to add both filtering composition and the grid to the main layout of the application.

    layout.addComponents(filtering, grid);

Now it is a good place to save your changes and try them in your browser.

6. Creating a form to edit Customer objects

To edit and add Customer objects we need to create a form, that edits the values in our domain objects. This tutorial has two alternative methods to do that. Pick either of them.

6.1. Creating a form using Vaadin Designer

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

The form to edit Customer objects can be built using several methods of which the visual composition by drag 'n' drop is the most intuitive. Vaadin Designer is an Eclipse plugin that you can install and do WYSIWYG editing of your view code. We’ll use it to create the form and then hook the editing logic to it with Java.

Tip
If you are using another IDE or just prefer to compose your user interface with code, take the alternative step, Creating a form using plain Java, where the CustomerForm is composed using plain Java code.

6.1.1. Installing Vaadin Designer

Vaadin Designer comes as an integrated part of Vaadin Plugin for Eclipse. It can be installed easily via Eclipse Marketplace. Choose Help  Eclipse Marketplace

In the dialog, just search for Vaadin and click install to mark it for installation. Clicking Install Now will take you to choose the modules you want and accept the license agreement.

pluginEclipseMarketPlace2
Selecting Vaadin Plugin for Eclipse for installation in Eclipse Marketplace

If you get a security warning about the software containing unsigned content, just accept the warning by clicking OK. After installation, Eclipse asks if you want to restart. Click Yes.

Tip
When you use Vaadin Designer for the first time in the next step, it will ask for a license key. Get a key from https://vaadin.com/designer. If you are not willing to buy a license now, just acquire a trial license.

6.1.2. Creating the form design

The following screencast will show you how to produce the CustomerFormDesign.html, a design file we need in this tutorial. Use pause and slow motion to follow better what is being done in the video. Feel free to get creative!

Tip
At any point of the process, you can also switch to the markup mode where you can edit the raw content of the .html file. If you wish to take a shortcut or think you did something wrong when using the designer, you can just copy-paste the content of the final state to your own .html file.
Tip
With Vaadin Framework 8, make following things differently: For status' NativeSelect Component, set Itemtype as CustomerStatus enum. Use DateField Component for birthday, instead of PopupDateField.

At this point we only have a static mockup of the actual UI. To implement a functional form component, we need some Java code as well. Vaadin Designer automatically creates a similarly named Java class, but a good habit is to never touch the auto-generated file, in this case the CustomerFormDesign.java file. If you’d introduce a new field to your form, your changes to CustomerFormDesign would be overridden by the tooling. Instead, we’ll create a class called CustomerForm which inherits from the auto-generated CustomerFormDesign class.

Start by creating a new Java class with the name CustomerForm. In Eclipse, right click on the "my.vaadin.app" package and choose New  Class. Type in the name CustomerForm, define the superclass as my.vaadin.app.CustomerFormDesign and click finish.

From the superclass, we inherit all the UI elements that we named when using the designer. E.g. by simply referencing to "save" field in the CustomerForm, we’ll have access to the save button we previously created.

We will later need a reference to the currently edited Customer object, CustomerService and the MyUI that uses this class. Add these fields and a basic constructor that accepts MyUI as a parameter to the CustomerForm class:

private CustomerService service = CustomerService.getInstance();
private Customer customer;
private MyUI myUI;

public CustomerForm(MyUI myUI) {
    this.myUI = myUI;
}

Although the form is not yet fully functional, you might want to see what it looks like at this point. Add it as a field to the MyUI class:

private CustomerForm form = new CustomerForm(this);

Now let’s modify the init method in MyUI to show the form. Let’s wrap both the Grid and the CustomerForm in a horizontal layout and configure the Grid to use all of the available space more efficiently. Replace the line layout.addComponents(filtering, grid); with the following:

HorizontalLayout main = new HorizontalLayout(grid, form);
main.setSizeFull();
grid.setSizeFull();
main.setExpandRatio(grid, 1);

layout.addComponents(filtering, main);

If you now save your changes and reload your application page in a browser, you should see your CustomerForm next to the grid that lists your existing entities.

Let’s get back to the CustomerForm. The first thing we’ll need is to populate the options for the select. To add all enum values as valid selections, add the following line to the constructor:

status.setItems(CustomerStatus.values());

Let’s also improve the UX a bit. When building the design, we already emphasized the save button with a ValoTheme.BUTTON_PRIMARY style name. Thus, it would be natural if the enter-key would do the same action as clicking the save button. Assign a keyboard shortcut to the save button with this line in the constructor:

save.setClickShortcut(KeyCode.ENTER);

To finish our form, we need to create a public API that we will use in the next part from MyUI, to pass in a Customer object that the form should edit. We will also add some logic to actually save the changes. We’ll start by adding a Binder as a field to the CustomerForm class:

private Binder<Customer> binder = new Binder<>(Customer.class);

In the constructor of the CustomerForm class add the following line to configure the Binder:

binder.bindInstanceFields(this);

This configures the Binder to use all the similary named editor fields in this form to bind their values with their counterpart in the Customer class. For example, the CustomerForm.firstName TextField will be bound to the Customer.firstName property.

Create a setter method for the Customer field. Just type setCus in the body of the class and hit autocomplete (Ctrl+Space) and Eclipse will create a method stub for you. Complete it with the following implementation:

public void setCustomer(Customer customer) {
    this.customer = customer;
    binder.setBean(customer);

    // Show delete button for only customers already in the database
    delete.setVisible(customer.isPersisted());
    setVisible(true);
    firstName.selectAll();
}

In addition to saving the reference of the currently edited Customer object, we are calling the Binder.setBean method. This will initialise all fields in the form and automatically update the values in the domain objects as the corresponding field value changes in the user interface.

Tip
If the naming convention based databinding doesn’t fit your needs, you can use PropertyId annotation on fields to explicitly declare the edited property.

We’ll also want to ensure the form is visible and that focus goes to the firstName field to improve user experience. As we will be using the form to edit both new non-persisted objects and existing customers, we will also show the delete button only for customers that are already persisted in the backend.

The last thing we need to do is to handle save and delete button clicks. Add the following methods to the CustomerForm class:

private void delete() {
    service.delete(customer);
    myUI.updateList();
    setVisible(false);
}

private void save() {
    service.save(customer);
    myUI.updateList();
    setVisible(false);
}

Finally, we’ll add listeners to the buttons to call these methods. Adding these simple lambda expressions to the constructor will take care of that:

save.addClickListener(e -> this.save());
delete.addClickListener(e -> this.delete());
Tip
For a truly re-usable form component in a real life project, you’d want to introduce an interface to replace the myUI field or, even better, use an event system like CDI events to completely decouple the components. We’ll leave that out of this tutorial for simplicity.

6.2. Creating a form using plain Java

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

This is an alternative step to the Creating a form using Vaadin Designer, where you’ll build the form UI programmatically in plain Java. If you already completed the step using Vaadin Designer, you can proceed to Connecting the form to the application.

The following video shows how to create a form using plain Java:

Start by creating a new Java class with the name CustomerForm. In Eclipse right click on the "my.vaadin.app" package and choose New  Class. Type in the name CustomerForm, define the superclass as com.vaadin.ui.FormLayout and click finish.

In the form, we’ll need editor fields for each property in our Customer domain class. There are different kinds of fields in Vaadin for editing different kinds of properties. In this example, we’ll use a TextField, a DateField and a NativeSelect. Add the following field declarations and action buttons as Java fields to the CustomerForm:

private TextField firstName = new TextField("First name");
private TextField lastName = new TextField("Last name");
private TextField email = new TextField("Email");
private NativeSelect<CustomerStatus> status = new NativeSelect<>("Status");
private DateField birthdate = new DateField("Birthday");
private Button save = new Button("Save");
private Button delete = new Button("Delete");

Also, we will later need a reference to the currently edited Customer object, CustomerService and the MyUI that uses this class. Add these fields and a basic constructor that accepts MyUI as a parameter to the CustomerForm class:

private CustomerService service = CustomerService.getInstance();
private Customer customer;
private MyUI myUI;

public CustomerForm(MyUI myUI) {
    this.myUI = myUI;

    setSizeUndefined();
    HorizontalLayout buttons = new HorizontalLayout(save, delete);
    addComponents(firstName, lastName, email, status, birthdate, buttons);
}

In the constructor we make the form size undefined, which practically means it will consume the minimum space defined by its content. Then we’ll just add all the fields to the CustomerForm and add action buttons to the bottom - side-by-side using a HorizontalLayout. Although the form is not yet fully functional, you might want to see what it looks like at this point. Add it as a field to the MyUI class:

private CustomerForm form = new CustomerForm(this);

Now let’s modify the init method in MyUI to show the form. Let’s wrap both the Grid and the CustomerForm in a horizontal layout and configure the Grid to use all of the available space more efficiently. Replace the line layout.addComponents(filtering, grid); with the following:

HorizontalLayout main = new HorizontalLayout(grid, form);
main.setSizeFull();
grid.setSizeFull();
main.setExpandRatio(grid, 1);

layout.addComponents(filtering, main);

When you now save your changes and reload your application page in your browser, you should see your CustomerForm next to the grid that lists your existing entities.

Let’s get back to the CustomerForm. The first thing we’ll need is to populate the options for the select. To add all enum values as valid selections, add the following line to the constructor:

status.setItems(CustomerStatus.values());

Let’s also improve the UX a bit. The most common thing your users will want to do with this kind of form is to save it. Let’s decorate the button with a style name that makes it more prominent in the UI and give it a keyboard shortcut - simply an enter hit in this case:

save.setStyleName(ValoTheme.BUTTON_PRIMARY);
save.setClickShortcut(KeyCode.ENTER);

To finish our form, we need to create a public API that we will use in the next part from the MyUI, to pass in a Customer object that the form should edit. We will also add some logic to actually save the changes. We’ll start by adding a Binder as a field to the CustomerForm class:

private Binder<Customer> binder = new Binder<>(Customer.class);

In the constructor of the CustomerForm class add the following line to configure the Binder:

binder.bindInstanceFields(this);

This configures the Binder to use all the similary named editor fields in this form to bind their values with their counterpart in the Customer class. For example, the CustomerForm.firstName TextField will be bound to the Customer.firstName property.

Create a setter method for the Customer field. Just type setCus in the body of the class and hit autocomplete (Ctrl+Space) and Eclipse will create a method stub for you. Complete it with the following implementation:

public void setCustomer(Customer customer) {
    this.customer = customer;
    binder.setBean(customer);

    // Show delete button for only customers already in the database
    delete.setVisible(customer.isPersisted());
    setVisible(true);
    firstName.selectAll();
}

In addition to saving the reference of the currently edited Customer object, we are calling the Binder.setBean method. This will initialise all fields in the form and automatically update the values in the domain objects as the corresponding field value changes in the user interface.

Tip
If the naming convention based databinding doesn’t fit your needs, you can use PropertyId annotation on fields to explicitly declare the edited property.

We’ll also want to ensure the form is visible and that the focus goes to the firstName field to improve the user experience. As we will be using the form to edit both new non-persisted objects and existing customers, we will also show the delete button only for customers that are already persisted in the backend.

The last thing we need to do is to handle save and delete button clicks. Add the following methods to the CustomerForm class:

private void delete() {
    service.delete(customer);
    myUI.updateList();
    setVisible(false);
}

private void save() {
    service.save(customer);
    myUI.updateList();
    setVisible(false);
}

Finally, we’ll add listeners to the buttons to call these methods. Adding these simple lambda expressions to the constructor will take care of that:

save.addClickListener(e -> this.save());
delete.addClickListener(e -> this.delete());
Tip
For a truly re-usable form component in a real life project, you’d want to introduce an interface to replace the myUI field or, even better, use an event system like CDI events to completely decouple the components. We’ll leave that out of this tutorial for simplicity.

7. Connecting the form to the application

Tip
Starting from this step directly? Download the project for this step, extract the zip file and choose Import…​  Maven  Existing Maven project.

In this part, we’ll use the CustomerForm class, which we created in the previous step, from the MyUI class. We will use it for both editing the existing customers and creating new ones.

The following video shows how to do this step of the tutorial:

In the previous part, we already added the form to the MyUI to see what it looks like. By default, we want it to be invisible, so let’s first hide it by adding this line to the init method of MyUI class:

form.setVisible(false);

To edit the customer chosen from the Grid, add the following selection listener to the end of the init method:

grid.asSingleSelect().addValueChangeListener(event -> {
    if (event.getValue() == null) {
        form.setVisible(false);
    } else {
        form.setCustomer(event.getValue());
    }
});

In the listener, we simply take the Customer object of the selected row and pass it to the CustomerForm for editing. In the previous step, we added a side effect to the setCustomer method that will bind the domain object to the corresponding fields and make it visible. If the selection is empty, we’ll hide the form.

To allow users to also create new customer records, we’ll create a simple "Add customer button" to the top of the UI, right next to the filtering composition we have already built from a CssLayout, a TextField and a Button. Introduce the new Button with a click listener, by adding the following lines to the init method, right after where you introduced the filtering composition:

Button addCustomerBtn = new Button("Add new customer");
addCustomerBtn.addClickListener(e -> {
    grid.asSingleSelect().clear();
    form.setCustomer(new Customer());
});

In the click listener, we first clear a possible selection from the grid and then instantiate a new Customer object and pass that to the form for editing.

To add it beside our filtering composition, we can use a HorizontalLayout to create a toolbar where we place both components. First, introduce a toolbar like this after the previously created addCustomerBtn:

HorizontalLayout toolbar = new HorizontalLayout(filtering, addCustomerBtn);

And, again, replace the line that populates your main layout to add the toolbar instead of just the filtering composition, which we just moved to the toolbar layout.

layout.addComponents(toolbar, main);

All planned features are now done. You can save the changes and play around with the application. If something went wrong, you can also download an example of the final application and see what went wrong.

8. It works! What next?

Congratulations! Users can now create, read, update and delete customer records stored in the demo backend and you have completed creating your first CRUD UI with Vaadin.

If you are an experienced Java developer, you are probably already full of ideas of how you can use your existing skills and create new shiny web UIs for your existing Java apps. If you want more ideas of how to create full stack applications, you might, for example, go through the Creating CRUD UI with Vaadin guide and create a bit similar UI with a real database backend implemented with Spring Data JPA. We have also collected a couple of other resources for an easy start in your Vaadin developer career.