Vaadin 10 is an almost complete rewrite of the successfull Vaadin framework and offers many new interesting and usefull features. One interesting feature is the router, that will superseed the navigator of Vaadin 8. With the @Route annotation placed at the type definition of a view class, it is possible to use a template for this view class that will make layouting a Vaadin application nice and easy.

Layouting with Vaadin 10

To demonstrate the new templating feature of the @Route annotation, I created a small sample project that can be downloaded from https://bitbucket.org/mekasorocks/vaadin10starter

I wanted to create a Vaadin application with this layout:

The Application Layout

The applicationlayout consists of

  • a header on top of the page that contains
    • a navigation on the left side of the header and
    • some buttons to switch the language (localeswitch) of our application on the right
  • a content area that will contain some form elements that are handled in view classes
  • a sticky footer on the bottom of the page

Using the @Route annotation

The @Route annotation for the default view (de.mekaso.vaadin.view.PersonView) of the project looks like

@Route(value = "", layout = ApplicationLayout.class)

The layout attribute must be a class that implements the com.vaadin.flow.router.RouterLayout interface. Lets look at this class in the project.

Creating a RouterLayout

The ApplicationLayout class is responsible for creating the layout for all our view classes:

@Theme(Lumo.class)
@PageTitle("Vaadin10 Starter Project")
@BodySize(height = "100vh", width = "100vw")
@StyleSheet("applicationlayout.css")
public class ApplicationLayout extends FlexLayout implements RouterLayout {
  ...
  @PostConstruct
  private void init() {
    // create the elements (header, content, footer)
  }
}

The annotations for theme, page title and the page size and self explanatory. The @StyleSheet annotation will be used to style the flexbox layout I used for the application. The ApplicationLayout extends the Vaadin FlexLayout class. The FlexLayout is based on the Flexbox css module. With flexbox you can easily create responsive layouts with just few lines of code and some CSS stylings. It is a fast and professional way to layout your application. Documentation and tricks about flexbox can be found at CSS Tricks or  W3Schools.

Create some layout elements

The init method of the ApplicationLayout class is automatically called by the CDI container by using the @PostConstruct annotation. Here the layout elements for header, content and footer are created and added to the FlexLayout container (lines 30 – 32). As you can see I gave the FlexLayout container an ID (“applicationlayout”) and added style classes to the elements of the layout. I used the ID and style classes to style and layout the elements in the stylesheet file applicationlayout.css.

@PostConstruct
private void init() {
  super.setId("applicationlayout");
  // navigation
  Div navigation = createNavigation();
  navigation.addClassName("navigation");
  // locale switch
  Div localeButtons = new Div();
  localeButtons.addClassName("localeswitch");
  for (Locale locale : this.i18nProvider.getProvidedLocales()) {
    Button localeButton = new Button(locale.getLanguage());
    localeButton.addClickListener(click -> {
      if (this.getUI().isPresent()) {
        this.getUI().get().setLocale(locale);
        this.localeChanger.fire(new LocaleChangeEvent(this.getUI().get(), locale));
      }
    });
    localeButtons.add(localeButton);
  }
  // header with navigation and locale switch
  this.header = new Div(navigation, localeButtons);
  this.header.addClassName("header");
  // the content
  this.contentContainer = new Div();
  this.contentContainer.addClassName("content");
  // sticky footer
  this.footer = new Div();
  this.footer.addClassName("footer");
  this.footer.add(new Text("Vaadin 10 Starterproject 2018"));
  add(this.header);
  add(this.contentContainer);
  add(this.footer);
}

Now all elements (except the actual content) are created and added to the application layout. We can already see the elements when calling the application in a web browser. However we need to tell the application layout class to add the content area to our layout and add the elements of the view classes to the content area when the view classes are called.

Populating the content area

The RouterLayout interface offers showRouterLayoutContent(HasElement content) method, that we need to override in order to place the content elements to our layout:

@Override
public void showRouterLayoutContent(HasElement content) {
  if (content != null) {
    this.contentContainer.removeAll();
    this.contentContainer.add(Objects.requireNonNull((Component)content));
  }
}

Without overriding the method the content elements of the view classes would be added after all other layout elements (at the bottom of the page). We just needed to remove all elements from the content container and add the content element to this container.

Styling the FlexLayout

Finally we need some lines of CSS to have a proper layout that will place the header on top, the content area in the middle and the footer on the bottom of the page:

#applicationlayout {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
}
#applicationlayout .header {
  padding: 10px;
}
#applicationlayout .content {
  flex: 1;
  padding: 10px;
}
#applicationlayout .navigation {
  float: left;
}
#applicationlayout .navigation vaadin-button {
  margin-right: 10px;
}
#applicationlayout .localeswitch {
  float: right;
}
#applicationlayout .localeswitch vaadin-button {
  margin-left: 10px;
}
#applicationlayout .footer {
  border-top: 1px dashed;
  text-align: center;
  padding: 10px;
}

Here you can see that I initialized the applicationlayout container with a flex layout (lines 1-5). The content area should use all remaining vertical space (lines 9-12) and the footer should remain on the bottom of the page with 10 pixel padding to the content. The result will look like that:

The responsive layout of the Vaadin 10 application
The responsive layout of the Vaadin 10 application

By using the features of RouterLayout you can create Vaadin 10 applications with a flexible layout for all your view classes. This whole concept of templating is very similar to the (old-school) templating framework Tiles. I always liked the concepts of tiles as it was simple and straight to the point. Using this approach in Vaadin is a major progress and a cool new feature of this UI framework.

By Meik Kaufmann

I am a certified oracle enterprise architect and like to share my knowledge and experience that I gain in the projects I am working on.

Leave a Reply

Your email address will not be published. Required fields are marked *