DS Vaadin Flow Gradle Plugin May 29th, 2019

Create a new Java project

The DS Vaadin Flow Gradle Plugin supports Java project out-of-the-box and integrates seamlessly with both the Gradle Java Plugin and the Gradle WAR Plugin.

Creating the initial build.gradle configuration

To create a new Java project you will need the following build.gradle file:

build.gradle

1
2
3
plugins {
    id 'com.devsoap.vaadin-flow' version '1.2'
}

On line 1 we are are defining the plugins block. The plugins block defines what plugins will be applied to the project.

On line 2 we include the DS Vaadin Flow Gradle Plugin which will provide us with all the necessery Vaadin tasks and configurations for us to build a Vaadin application.

That is all we need, the DS Vaadin Flow Gradle Plugin will automatically apply the Gradle Java Plugin to the project, we don’t need to do it here.

build.gradle

1
vaadin.autoconfigure()

vaadin.autoconfigure() is a convenient way of starting a new project when you aren’t yet familiar with the the dependencies needed for a Vaadin Flow project. It will set up the repositories required for the project, configure the project to have all core dependencies and automatically select the Lumo theme as default.

Alternatively, if you do not want to use vaadin.autoconfigure() then you can also define the repositories and dependencies manually. The Vaadin plugin also provides helpers for you when doing this.

build.gradle

1
2
3
4
5
6
7
8
9
10
11
// Manually defining the Vaadin dependencies for a Java project
repositories {
    vaadin.repositories()
}

dependencies {
    vaadin.bom()
    vaadin.core()
    vaadin.lumoTheme()
    vaadin.slf4j()
}

On line 3 all the required repositories are added. The plugin provides a nice helper for you so you don't have to remember any of the Vaadin repository urls.

On line 7 we add the Vaadin BOM dependency. The BOM dependency locks down all transitive dependency versions to versions of the dependencies that are compatible with eachother. This is important since once you start adding addons that might depend on conflicting versions it could otherwise brake.

On line 8 we add the Vaadin Flow Core framework. These include all the framework code as well as all Open Source dependencies.

On line 9 we add a dependency to the Lumo base theme which will define how our UI will look like.

On line 10 we add a Logging implementation. This is optional and if you wish you could switch it out to another Logging implementation.

Creating application stubs

Now that we have the build.gradle file configured we are ready to create the application source files.

The DS Vaadin Flow Gradle Plugin comes with the following out-of-the-box tasks for creating different source files:

Since we are creating a new project, we are going to go with the vaadinCreateProject task.

1
gradle vaadinCreateProject --name MyProject --package com.example

Once you have run that task you should see the following folder structure:

.
├── build.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           ├── MyProjectServlet.java
        │           ├── MyProjectUI.java
        │           └── MyProjectView.java
        └── webapp
            └── frontend
                └── styles
                    └── myproject-theme.css

8 directories, 5 files


Lets have a look at the created files one-by-one.

MyProjectServlet.java

1
2
3
4
5
6
7
8
9
package com.example;

import com.vaadin.flow.server.VaadinServlet;
import com.vaadin.flow.server.VaadinServletConfiguration;
import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns = '/*', name = 'MyProjectServlet', asyncSupported = true)
@VaadinServletConfiguration(ui = MyProjectUI.class, productionMode = false)
public class MyProjectServlet extends VaadinServlet { }

As the name of the file describes, the Servlet class will configure our Vaadin Flow servlet. In this class we do not need to implement or override anything, everything is configured using annotations.

@WebServlet annotation is a standand Java EE Servlet 3 annotation for declaring a Servlet 3 servlet. In the generated code we define the Vaadin servlet to listen to the root context (/) of the server. It also enables the asyncronous support for the servlet as Vaadin by default supports it.

@VaadinServletConfiguration is used to further configure the Vaadin Flow specific servlet parameters. In our case it points us to the main UI of the application as well as turns of production mode by default.

Even though productionMode=false here the plugin can enable the production mode in other ways. Read more about production mode in the section about production mode configuration.

All Vaadin Flow application servlets should extend the VaadinServlet. The VaadinServlet is a standard Java servlet with Vaadin specific implementation for handling HTTP requests.

MyProjectUI.java

1
2
3
4
5
6
7
8
9
10
11
package com.example;

import com.vaadin.flow.component.dependency.HtmlImport;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.theme.lumo.Lumo;
import com.vaadin.flow.theme.Theme;

@HtmlImport("frontend://styles/myproject-theme.html")
@Theme(Lumo.class)
public class MyProjectUI extends UI { }

The UI is responsible for rendering the Vaadin Flow application.

By default the implemention of the UI is empty and it will automatically be initializated with the main view, but if we want lower level access then it is advisable to create your own UI.

For example, if you want to get the request parameters you can override the init(VaadinRequest request) method of the UI and read the parameters from the provided VaadinRequest.

In some cases, for instance when using Spring Boot, no UI instance is required.

MyProjectView.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.example;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.page.BodySize;
import com.vaadin.flow.component.page.Viewport;
import com.vaadin.flow.router.Route;

@Route('')
@BodySize(height = '100vh', width = '100vw')
@Viewport('width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes')
class MyProjectView extends VerticalLayout {

    MyProjectView() {

        className = 'app-view'

        add new Label('Hello Java app!')

        add new Button('Click me!', { event ->
             event.source.with {
                text = 'Clicked!'
                className = 'clicked'
            }
        })
    }
}

The view class is what the end-user sees when accessing the application url.

The @Route annotation configures on which sub-path the view is displayed. The path is relative to the application path so if you for example are hosting the Vaadin application at https://example.com/myproject and you would have defined your route to be @Route('roxx') then your view would be accessable at https://example.com/myproject/roxx.

Using the @BodySize annotation we can configure the size of the root body tag. In most cases when building an application you will want your application to take up all the space of the browser window, so by default it is set to 100vh (100 % of the viewport height) and 100vw (100% of the viewport width).

We can also further tweak how the application can scale when the user zooms in or out by using the @Viewport annotation.

One thing to remember is that every view needs to extend a Vaadin Component. By default the default view will use the VerticalLayout which will stack the components vertically.

The created default application will add a Label as well as a Button with an event-handler to demonstrate how to add a few components to the view.

myproject-theme.css

1
2
3
4
5
/*
 * This file contains the Application theme
 */
label { color: green; }
label.clicked { color: red; }    

A CSS theme file for the application is also created for your convenience. The theme file is by default imported in MyProjectUI.java.

How can a CSS file work HTML imports?
By default any CSS file placed in /webapp/frontend/styles will automatically be wrapped in a HTML wrapper. That is why we can simply use CSS files and not always wrap the css in a HTML file that is done in many Maven project examples. IF you want to have a look at how the HTML wrappers will look like then look into /build/webapp-gen/frontend/styles where the generated will exist.