Visually Designing Views for Java Web Apps
Published: 2021-08-27 15:50:05

In this article, I'll show you how to visually design GUIs by dragging and dropping UI components like buttons, text fields, combo boxes, and more, onto a 'canvas' (the web page or view). You'll also learn how to connect this design to a Java backend.

The tool that makes this possible is called [Vaadin Designer](https://vaadin.com/designer). Although not a free product, you can try it out, something I strongly suggest, since it highly reduces the time needed to implement user interfaces for the web in Java applications.

If you prefer, there's a video version of this article:

Creating a New Project
----------------------

Go to [https://start.vaadin.com](https://start.vaadin.com/) and generate a new Maven project. When prompted, pick **Flow (Java)**:

![Vaadin Welcome Screen](https://dz2cdn1.dzone.com/storage/temp/15073594-screenshot-2021-08-17-at-94021.png)

The tool allows you to preconfigure the application to be generated. You'll find all the options on the left side of the page. In particular, the **Views** tab, on the top left corner, allows you to add views to the application. You can find many useful types of views that serve as starting points that you can modify later in IntelliJ IDEA. However, in this tutorial, we want to have a clean project with no views. We'll create our own from scratch.

Delete all the views that are created by default (**Hello World**, and **About**). Click the **trash can icons** to delete each view. The views tab should be empty now:

![Tabs After Deleting Defaults](https://dz2cdn1.dzone.com/storage/temp/15073596-screenshot-2021-08-17-at-94030.png)

Click the **Download** button, extract the contents of the zip file and [import](https://vaadin.com/learn/tutorials/import-maven-project-intellij-idea) the [Maven](https://vaadin.com/learn/tutorials/learning-maven-concepts) project in IntelliJ IDEA.

Installing Vaadin Designer
--------------------------

You need to install the Vaadin Designer [plugin](https://plugins.jetbrains.com/plugin/9519-vaadin-designer) for IntelliJ IDEA. You will also need to set up a trial license. The process is pretty simple. Check the instructions [here](https://vaadin.com/trial).

If you are on Linux or Windows, go to **File | Settings** in IntelliJ IDEA. If you are on macOS, go to **IntelliJ IDEA | Preferences**. Select **Plugins** on the list to the left of the window. Type **vaadin** in the search box, and install **Vaadin Designer**. Make sure not to select Vaadin Designer for framework 7! This is an old version of the plugin that is not compatible with recent versions of Vaadin:

![Selecting Vaadin to Install](https://dz2cdn1.dzone.com/storage/temp/15073598-screenshot-2021-08-17-at-94009.png)

You might have to restart the IDE, but once the installation process is completed, you are all set to start creating views in a visual way.

Adding a New Design
-------------------

Select **File | New | Vaadin 10+** design from the menu. Change the name of the view to **demo-view** and click on **OK**:

![Creating New Vaadin 10 Design](https://dz2cdn1.dzone.com/storage/temp/15073635-screenshot-2021-08-17-at-100356.png)

This creates two files:

* `frontend/demo-view.ts`: A TypeScript file maintained by Vaadin Designer. You don't need to manually edit this file. Instead, you indirectly modify it by using Vaadin Designer when you drag and drop UI components to the view.
* `src/main/java/com/example/app/DemoView.java`: A Java companion file that you can use to add behavior to the view. For example, click listeners and calls to back-end services.

Double-click the `demo-view.ts` file to open the visual designer. The first time you open a file like this, IntelliJ IDEA will perform an indexing operation that might take some time. Be patient, you'll be able to instantly open files after this process is completed.

Selecting a Template
--------------------

When you open the design file in IntelliJ IDEA, Vaadin Designer will show you a set of templates that you can use as a starting point for the design of your view or page. Select **Header & footer with sidebar** from the list:

![Selecting Template Design](https://dz2cdn1.dzone.com/storage/temp/15075952-screenshot-2021-08-17-at-125731.jpg)

Adding UI Components to The View

On the left side of the screen, you'll see the list of UI components that are available. Things such as layouts (vertical, horizontal, split, etc.), buttons, charts, date pickers, grids, selection components (like combo boxes and radio buttons), and many more. Since the list is quite large, you can search by name. Search for **vertical** and from the list, drag a vertical layout to the canvas (which is the view or web page we are visually building):

![Dragging Vertical Layout to Canvas](https://dz2cdn1.dzone.com/storage/temp/15075897-screenshot-2021-08-17-at-130815.jpg)

Using the same approach, search for **h1** and drag an h1 component to the view on top of the vertical layout we previously added:

![Adding H1 Component](https://dz2cdn1.dzone.com/storage/temp/15075902-screenshot-2021-08-17-at-131207.jpg)

You can also drag UI components to the **Outline** view instead of the view. This is useful when you want to add a UI component to a specific layout when several of these are nested. It gives you more fine-grain control on where exactly to drop a UI component. Use this technique to drag a **Vaadin Text Field** inside the vertical layout that we previously added:

![Dragging Vaadin Text Field](https://dz2cdn1.dzone.com/storage/temp/15075910-screenshot-2021-08-17-at-131609.jpg)

Continue the process and add a **Date Picker**, and a **Button**. If you make a mistake and drop the UI component on the wrong layout, you can drag it again and drop it, in both, the view or the **Outline**. Here is the result:

![Viewing Outline](https://dz2cdn1.dzone.com/storage/temp/15075925-screenshot.jpg)

Configuring UI Components
-------------------------

When you drop UI components to the view, the labels, texts, placeholders show a default value that you most likely want to change. You can change this, and other properties of a UI component in the **Outline**. Right on the bottom of the **Outline**, you'll find a list of properties and configurations for the selected UI component.

Select the **h1** component in the view or the **Outline** and change the **Text** property to something like "Vaadin Designer Demo":

![Configuring H1 Component](https://dz2cdn1.dzone.com/storage/temp/15075942-screenshot-2021-08-17-at-133311.jpg)

Select the **Vaadin Text Field** and change the **label** property to "Enter your name:", and remove the content of the **placeholder** property (or specify the string you'd like to see there).

Repeat the process to configure the **Date Picker**. Change the label **property** to "Your birth date:". For the **Button**, change the **Text** property to "Send". Here's the result:

![Results of Configuration](https://dz2cdn1.dzone.com/storage/temp/15075949-screenshot-2021-08-17-at-133822.jpg)

Adjusting the Layout
--------------------

The margin, size, alignment, and other properties of UI components can be easily adjusted using the options in the lower section of the **Outline** panel. Select the vertical layout that contains another vertical layout and center the alignment:

![Selecting Another Vertical Layout](https://dz2cdn1.dzone.com/storage/temp/15092348-screenshot-2021-08-23-at-141347.jpg)

For the text field and date picker, set the alignment option shown in the following screenshot to make the fields use all the horizontal space in the layout:

![Setting Alignment Option](https://dz2cdn1.dzone.com/storage/temp/15092356-screenshot-2021-08-23-at-144044.jpg)

Try placing the button to the right side of the layout using the corresponding alignment option.

Adding a Java Back-End Service
------------------------------

Time to code! We need a Java back-end service that we'll implement as a simple class with one method. Add the following class to the project:

```Java
package com.example.app;

import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

@Service
public class BackendService {

    public String greet(String name, LocalDate birthDate) {
        if (name == null || name.isEmpty() || birthDate == null) {
            return "So... what's your name?";
        } else {
            long age = ChronoUnit.YEARS.between(birthDate, LocalDate.now());
            return String.format("Hello, %s. You are %d years old", name, age);
        }
    }

}
```
​
This class has a method that returns a string with a personalized message telling the age of the person given their birth date. Notice that the class is annotated by `@Service`. This is a Spring annotation that makes instances of this class injectable when you add a parameter in the constructor of another class. We'll see it in action shortly.

Accessing the UI Components From Server-Side Java
-------------------------------------------------

We need to access the values in the text field and date picker from the server-side Java code. We also need to add a click listener to the button so that we can send the data in the input fields to the backend service that we created. First, we need to configure the names of the Java properties that we want to use for each UI component that we want to access programmatically. This is done by setting the **id** property. Use `name`, `birthDate`, and `send` for the text field, the date picker, and the button:

![Configuring id Property](https://dz2cdn1.dzone.com/storage/temp/15092406-screenshot-2021-08-23-at-150838.jpeg)

Second, we need to click the little buttons that appear with you place the mouse pointer over the components in the **Outline** panel. Do it for the three UI components we need—text field, date picker, and button:

![Selecting Tiny Buttons](https://dz2cdn1.dzone.com/storage/temp/15092414-screenshot-2021-08-23-at-151147.jpg)

If you check the `DemoView` Java class, you'll see the Java properties with the names we configured:

```Java
@Tag("demo-view")
@JsModule("./demo-view.ts")
@Route("")
public class DemoView extends LitTemplate {

    @Id("send")
    private Button send;
    @Id("birthDate")
    private DatePicker birthDate;
    @Id("name")
    private TextField name;
  
	...
}
```

Connecting the Backend Service to The View
------------------------------------------

We have a back-end service and the UI components in Java. Connecting them is pretty simple now. Change the constructor of the `DemoView` class to the following:

```Java
...
public DemoView(BackendService backendService) {
    send.addClickListener(event -> {
        String message = backendService.greet(name.getValue(), birthDate.getValue());
        Notification.show(message);
    });
}
...
```

The code is easy to understand. We send the values in the text field and the date picker to the back-end service, assign the result to a `String`, and show it as a notification in the browser. Notice how we injected an instance of the `BackendService` class. Spring is in charge of this and you don't need to worry about creating the instance. In technical terms, both, instances of the `DemoView` and the `BackendService` classes are created and managed by Spring.

Exposing the View to The Browser
--------------------------------

To make the view we previously designed available through the web browser, we have to assign it to a _route_. Add the `@Route` annotation to the `DemoView` class as follows:

```Java
@Tag("demo-view")
@JsModule("./demo-view.ts")
@Route("")
public class DemoView extends LitTemplate {
	...
}
```

This makes the view available at [http://localhost:8080](http://localhost:8080) when we start the application. If we wanted something like [http://localhost:8080/demo,](http://localhost:8080/demo,) then we could have used `@Route("demo")`.

Running the Application
-----------------------

Everything is ready. Run the application by executing the `main` method in the `Application` class by right-clicking on it and selecting **Run 'Application'**. It might take some time the very first time that you run the application. This is because Maven downloads all the Java dependencies to a local repository and the same happens with the client-side dependencies. Subsequent runs are much, much faster.

Once the process is completed, a new browser tab (or window, if needed) is automatically opened for you. Here's a screenshot of the application:

![Screenshot of Application](https://dz2cdn1.dzone.com/storage/temp/15092438-screenshot-2021-08-23-at-152659.png)

Additional Resources
--------------------

To learn more about Vaadin check out the quick [start tutorial](https://vaadin.com/docs/v14/flow/tutorials/quick-start-tutorial). Or if you want to learn how to build a full-blown application with Spring Boot and Vaadin, check the more [in-depth course](https://vaadin.com/docs/v14/flow/tutorials/in-depth-course).