Sven Ruppert

App-Layout for Flow

Intro

A web application can target a wide variety of audiences. In our case, I assume a web application that is used to support internal processes in a company. This is a typical business application, which has probably been seen by just about every developer. The web interfaces in this area are quite often based on the experiences made with the classic desktop applications.

Minimal Requirements

In our minimal version, we will assume that there will be a menu in the application header. The number of menu entries is limited to four to five and is, therefore, no challenge for a screen. Of course, on the assumption that the terms used are a little shorter than some German words, such as "Gleisschotterrbettungsreinigungsmaschine."

Note

An online demo is deployed on Heroku or try it on your machine inside Docker:

docker pull vaadintutorials/flow-layout-app_layout-vaadin
docker run -p8899:8899 --name demo vaadintutorials/flow-layout-app_layout-vaadin

For more details have a look at the github repo.

The Layout

The web application layout is a frame that contains the menu header and a slot for views. Here we have the challenge for the first time that the navigation should not replace the contents of the entire window, only the area where the views are shown. The following image illustrates the structure.

The views are shown in the area marked "Products."

The basic structure

The basic framework that will be used here is based on the App Layout component by Vaadin. The App Layout handles routing using RouterLayout.

To start with Vaadin’s AppLayout, we’ll create a class named MainLayout, extending the class AppLayout.

Note

If you are using the following dependency, the component app-layout is already available in your classpath.

    <dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin</artifactId>
    </dependency>

If not, the corresponding maven dependency is

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-app-layout-flow</artifactId>
</dependency>

The app-layout will be customized inside the constructor or the class MainLayout. For this you have to use the methods addToDrawer, setContent and addToNavbar.

setContent

With this method, the actual content of the working area is set. Here in this example is is used only once after the user had passed the login process.

setContent(new Span("click in the menu ;-) , you will see me never again.."));

addToNavbar

This method is used to set the navigation bar and the Icon that will be shown in the upper left corner. First, the Icon itself is loaded, and the height is fixed to 44px. The instance of the class DrawerToggle is used to make the navigation bar responsive. Technically it is a specialised button with the provided Icon that is used to open and close the navigation bar itself.

    StreamResource res = new StreamResource(LOGO_PNG ,
                                            () -> MainView.class.getResourceAsStream("/" + LOGO_PNG));
    Image img = new Image(res , "Vaadin Logo");
    img.setHeight("44px");
    addToNavbar(new DrawerToggle(), img);

addToDrawer

The method addToDrawer is responsible for setting the main menu itself. The menubar is implemented with Tabs. Every tab is one visible menu entry of the navigation bar at the left side. We need to define a connection between an entry in the menu bar and a component for the content area. For this, a map is used to hold both references. The key inside the map is the tab itself, and the value in the map is the component for the content area.

private Map<Tab, Component> tab2Workspace = new HashMap<>();

  private Tab dashBoard() {
    final Span label = new Span(getTranslation(ITM_DASHBOARD));
    final Icon icon  = DASHBOARD.create();
    final Tab  tab   = new Tab(new HorizontalLayout(icon,label));
    tab2Workspace.put(tab, new DashboardView());
    return tab;
  }
    final Tabs tabs = new Tabs(dashBoard(), user(), trends(), logout());
    tabs.setOrientation(Tabs.Orientation.VERTICAL);
    tabs.addSelectedChangeListener(event -> {
      final Tab selectedTab = event.getSelectedTab();
      final Component component = tab2Workspace.get(selectedTab);
      setContent(component);
    });
    addToDrawer(tabs);
Note

This example is using the I18Provider from Flow. To read more about this, I recommend our tutorials about Internationalizing in Flow

To use the layout now, you have to assign the attribute layout with the class MainLayout to the participating views in the @Route annotation.

@Route(value = MainView.NAV_MAIN_VIEW, layout = MainLayout.class)
public class MainView extends Composite<Div> implements HasLogger {
  public static final String NAV_MAIN_VIEW = "main";

  public MainView() {
    getContent().add(new Span("Page content"));
  }
}

Summary

We now have a straightforward framework of an application with a structure typical of today. The functionalities are limited, but sometimes that is quite enough. However, if you want a little more extensive options, you can take a look around in the Vaadin Directory for alternatives or use the more fully-featured Business App starter.

I will take a closer look at a few other ones of them in the next parts of this series.

Vaadin is an open-source framework offering the fastest way to build web apps on Java backends
GET STARTED

Comments (4)

Tatu Lund
2 years ago May 25, 2020 11:42am
ali akbar shahriari garaei
2 years ago May 25, 2020 12:51pm