Introduction to Vaadin Flow

Flow is the part of the Vaadin platform that connects the Java ecosystem with the Web Platform. This chapter gives an overview to Vaadin Flow Architecture and introduces Flow’s basic concepts.

Architecture

Working with low-level web technologies is time-consuming and hard. In Vaadin platform, all user interface elements are componentized into Web Components, meaning that they are de-coupled and sandboxed, making web development easier than ever before. As part of Vaadin platform, Flow provides a type-safe Java server-side API to use these Web Components. Flow provides automated bi-directional communication between the server and the browser giving Java developers full access to all of the modern web and makes it easier to connect the UI to data via a robust Java backend than using traditional REST-based communication.

With Vaadin Flow you can access browsers APIs, Web Components, or even simple DOM-elements, directly from the server-side Java. When using Vaadin Flow, you do not need to understand how the client to server communication or the Web Components work. You can just focus on using and creating Components which work at a much higher abstraction level.

If necessary, you are also able to take full control over what gets sent through the wire when creating components based on HTML templates. Flow provides two-way data binding so that when the UI is changed on the client or the server, the changes are automatically reflected on the other side.

Building UIs with Components

The core of Vaadin Flow is UI Components, that are used to build interactive web apps and websites. On top of ready-made components, there are powerful abstraction layers that can be used to create new components.

Vaadin Components

On the high abstraction layer, you can build UIs, in a highly productive way, by using the Java APIs for Vaadin’s Web Components. This way you don’t have to write or understand any JavaScript or HTML, and CSS is only necessary to give your App the look and feel you want to.

TextField textField = new TextField();
Label greeting = new Label("Hello stranger");

textField.addValueChangeListener(event ->
      greeting.setText("Hello " + event.getValue()));

VerticalLayout layout = new VerticalLayout(textField, greeting);

To discover the available components, see Using Vaadin Components.

Composing new Components in 100% Java

On the next abstraction layer, you can easily create new components by customizing and mixing existing components enabled by a light-weight component architecture and the possibility to access the DOM and browser APIs from the server side. This allows you to work out issues and customize things, while still staying on the server side and leveraging Flow’s automated communication layer between the browser and the server.

@Tag("my-label")
    public class MyLabel extends Component {
        public void setText(String text) {
            getElement().setText(text);
        }

        public String getText() {
            return getElement().getText();
        }
    }

See the tutorials in the Creating Components section to learn how to build components with a reusable API, and the Element API section to learn how to access and customize the DOM from the server side.

Integrating a Web Component

With Vaadin Flow, you can take any Web Component, create a Java API for them, and start using them in your projects.

@Tag("game-card")
@HtmlImport("bower_components/game-card/game-card.html")
public class GameCard extends Component {

}

For more information, see the tutorials in the Integrating a Web Component section.

You can find ready-made Java APIs for Web Components published by the Vaadin Community in the Vaadin Directory.

Building Components with HTML Templates

On the lowest level, it is possible to take full control of the DOM and communication, by creating components as HTML templates, and creating a server-side Java class that encapsulates them into reusable components with a high-level API. To help build the templates, Flow provides:

  • A Model to share and synchronize data between the Java code and the HTML template,

  • a server-side representation of the client-side DOM tree for dynamic modifications,

  • and a type-safe Java RPC API for interacting with JavaScript in the browser.

<template>
    <vaadin-vertical-layout>
        <vaadin-text-field id="textField"></vaadin-text-field>
        <label id="greeting">Hello stranger</label>

        <input type="color" on-input="updateFavoriteColor">
        <label>Favorite color: </label>
    </vaadin-vertical-layout>
</template>
private @Id("textField") TextField textField;
private @Id("greeting") Label greeting;

// Setting things up in the component's constructor
textField.addValueChangeListener(event ->
      greeting.setText("Hello " + event.getValue()));

// Instance method in the component published to the client
@EventHandler private void updateFavoriteColor(
      @EventData("event.target.value") String color) {
    getModel().setColorCode(color);
}

See the tutorials in the Creating Polymer Templates section for more information.

Routing and Navigation

Flow provides the Router class to help structuring the web application or site into different logical parts that the user can navigate into. Registering navigation targets is done by annotating the component with @Route. You can specify a path, and optionally, a parent layout to display the component in.

// register the component to url /company and show it inside the main layout
@Route(value="company", layout=MainLayout.class)
@Tag("div")
public class CompanyComponent extends Component {
}

public class MainLayout extends Div implements RouterLayout {
}

See the tutorials in the Routing and Navigation section for more information.

How Flow Components Work

Flow allows Java code to control the DOM in the web browser with a server-side Java representation of the same DOM tree. All changes are automatically synchronized to the real DOM tree in the browser.

The DOM tree is built up from Element instances, each one representing a DOM element in the browser. The root of the server-side DOM tree is the Element of the UI instance, accessible using ui.getElement(). This element represents the <body> tag.

Elements on the server are implemented as flyweight instances. This means that you cannot compare elements using == and !=. Instead, use element.equals(otherElement) to check whether two instances refer to the same DOM element in the browser.

Element Hierarchy

A web application is structured as a tree of elements with the root being the element of the UI instance. An element can be added as a child of another element using methods such as element.appendChild(Element) for adding an element to the end of a parent’s child list or element.insertChild(int, Element) for adding to any position in the child list.

The element hierarchy can be navigated upwards using element.getParent() and downwards using element.getChildCount() and element.getChild(int).

Component Hierarchy

The component hierarchy provides an higher level abstraction on top of the element hierarchy. A component consists of a root element and can optionally contain any number of child elements. Components can be added inside other components using methods such as UI.add(Component), provided the parent component supports child components.

Composite is a special kind of component which does not have a root element of its own but instead encapsulates another component. The main use case for a composite is to combine existing components into new components while hiding the original component API.

The component hierarchy can be navigated upwards using component.getParent() and downwards using component.getChildren(). The component hierarchy is constructed based on the element hierarchy, so they are always in sync.

Templates

Instead of writing Java code for building the DOM from individual elements, it’s also possible to use an HTML template file to define the overall DOM structure and use a Java model to control the contents of the elements.

In addition to giving a clearer overview of the structure of a Component, the template functionality does also help to improve performance – the same template definition is reused for all component instances using the same template file. This means that less memory is used on the server and less data needs to be sent to the browser.

NEXT: Follow the tutorial to build your first Vaadin application: Getting started with Vaadin Flow