Introduction

In this article, we go through some concepts and features central to Vaadin development. While you do not necessarily need to know about all of them, they are good background knowledge about how Vaadin works.

Key Technologies

Vaadin is based on the following key technologies:

Java

Java is the leading server-side programming language for large web applications. With object-oriented programming and strong typing, it provides compile-time type safety, which makes applications more robust and easier to develop when they get large. The rich ecosystem around Java makes it ideal for many kinds of modern applications.

JavaScript

JavaScript is the native language in all modern browsers and is used is most web applications today. Vaadin components are Web Components programmed in JavaScript, with a Java API to enable using them on the server-side, without using any JavaScript.

Web Components

Web Components are a component model based in several technologies: custom HTML elements, shadow DOM that enables encapsulation, and HTML templates. All Vaadin components are web components, which can be used both in JavaScript and through the server-side Java API.

See webcomponents.org for more information about Web Components.

Cascading Stylesheets (CSS)

Vaadin applications are styled using cascading style sheets (CSS). Styling begins with a built-in theme, which can be modified and refined with application-specific style sheets.

Java Servlets

Vaadin server-side applications run as Java servlets. A Java Servlet is a class that is executed in a Java web server (a Servlet container) to extend the capabilities of the server. In practice, it is normally a part of a web application, which can contain HTML pages to provide static content, and JavaServer Pages (JSP) and Java Servlets to provide dynamic content.

npm

The Node.js Package Manager (npm) is used for managing JavaScript dependencies. Once all the JavaScript dependencies are collected, they are used for building the frontend bundle, together with CSS style sheets.

Rapid Web Application Development

At Vaadin, we pride ourselves on developer productivity. We feel that developers should be able to forget the framework they run on, so that they can concentrate on developing the best application they can.

Everything is a Component

Vaadin uses a component-based programming model to build UIs. Reusable components are the cornerstone of Vaadin. Everything in the UI is a component. To have a button, you create a button component. To have a text input field, you create a TextField component. You can build your own components and views by combining existing components and layouts, or by creating creating a new web component and connecting it with a server-side counterpart.

Each server-side component is connected to web components and HTML elements on the client-side.

The following is a small but complete Vaadin application written in Java:

In the example, the application itself is a UI component that extends one of Vaadin’s basic layouts – VerticalLayout. In the constructor, we add a H1 component (which corresponds to a h1 HTML tag) to the layout to say hello to the entire world.

Event-Driven Programming

To make the applications interactive, Vaadin provides an event-driven programming model. User interaction causes events, which are handled by event listeners.

In Java code, you can handle button clicks by adding a click listener with addClickListener(), typically as a lambda expression:

Button button = new Button("Push me!");

button.addClickListener(event ->
  button.setText("You pushed me!"));

When using Vaadin components in JavaScript, you add an event listener to the element:

const button = document.createElement('vaadin-button');
button.textContent = 'Push me!';
button.addEventListener('click', event => button.textContent = 'You pushed me!');

Flexible and Powerful Data Binding

All Vaadin components have a clear and unified data binding API to help developers build data-intensive apps with confidence.

How Vaadin Components Work

Vaadin 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 instance represents a DOM element in the browser. The root of the server-side DOM tree is the Element of the UI instance. You can access it using the ui.getElement() method. This element represents the <body> tag.

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

Element Hierarchy

A web app is structured as a tree of elements, with the UI instance element as the root. An element can be added as a child of another element, using methods such as:

  • element.appendChild(Element) to add an element at the end of a parent’s child list, or

  • element.insertChild(int, Element) to add an element to any position in a child list.

You can use element.getParent() to navigate upwards in the element hierarchy, and element.getChildren() to navigate downwards.

Component Hierarchy

The Component class wraps the Element and provides a higher level of abstraction. You can obtain the element representation of a component using the Component.getElement() method.

The component’s element can optionally contain any number of child elements. In addition to the low-level element, the component itself can also support child components, and methods similar to Component.add(Component…​ ) are provided for this purpose.

You can navigate through the component’s hierarchy using component.getParent() to navigate upwards, and component.getChildren() to navigate downwards.

The component hierarchy is constructed based on the element hierarchy. Changes in the component hierarchy are reflected in the element hierarchy (but not vice versa).

Building Java UIs with Components

Creating New Components in Java

On the higher abstraction layers, you can easily create custom components by adapting or combining existing components to meet your requirements.

The light-weight component architecture and the ability to access the DOM and browser APIs from the server-side, simplifies component customization. While staying on the server-side you can perfect customizations and eliminate bugs, by leveraging Vaadin’s automated communication layer between the browser and the server.

For example, you can extend Component to create a custom component as follows:

@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 Creating Components to learn how to build components with a reusable API, and Element API to learn how to access and customize the DOM from the server side.

Integrating a Web Component

Vaadin allows you to create a Java API for any available Web Component and then use the API in your projects.

For example, you can import the game-card Web Component into a GameCard Java class as follows:

@Tag("game-card")
@JsModule("./game-card.js")
public class GameCard extends Component {

}

See the tutorials in Integrating a Web Component for more.

You can also find prebuilt Java APIs for Web Components that have been published by the Vaadin Community in the Vaadin Directory.

HTML Templates

As an alternative to creating the DOM in Java, you can use HTML templates. In this case, Java is only used for server-side control and interaction with elements, for example via event listeners.

Possible benefits of this approach include:

  • A clearer overview of the structure of the component.

  • Improved performance. Because the same template definition is used for all component instances using the same template file, 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

Building Components with HTML Templates

Another way to create components is to separate the layout from the UI logic. The best way to do this is to use JavaScript modules and HTML templates together with Java classes. The JavaScript module contain the layout and (if needed) pure client-side logic, while the Java classes takes care of the server-side logic, like event handling.

You can use these components in the same way as any other component in your Java environment. Vaadin does not distinguish between pure Java or HTML/Java combined components.

For example, to do @Id injection in a component, you would first need the following template in JavaScript:

static get template() {
    return html`
        <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>`;
}

Now, you can inject the text field and the label in Java code by their IDs as follows:

// Inject the components by their IDs
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 Creating Polymer Templates for more details.

Routing and Navigation in Java component using Router

Vaadin provides the Router class to structure the navigation of your web app or site into logical parts.

You can use the @Route annotation to register navigation targets. You can specify a path, and optionally a parent layout class to display the component.

Example: Using the @Route annotation.

// 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 Routing and Navigation for more.