The app frame: AppLayout
Most applications have a frame: a header with the name on top, a menu on the left and an area where screens change. In Vaadin you build the frame once, in a layout class based on AppLayout. Views are placed into its central part automatically, and the header and menu are not redrawn when you move between them.
The application layout
// src/main/java/com/example/blog/views/MainLayout.java
package com.example.blog.views;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.sidenav.SideNavItem;
import com.vaadin.flow.router.Layout;
@Layout
public class MainLayout extends AppLayout {
public MainLayout() {
H1 title = new H1("Blog admin");
title.getStyle().set("font-size", "1.25rem").set("margin", "0");
SideNav nav = new SideNav();
nav.addItem(new SideNavItem("Hello", HelloView.class, VaadinIcon.HOME.create()));
nav.addItem(new SideNavItem("Draft", DraftView.class, VaadinIcon.EDIT.create()));
addToNavbar(new DrawerToggle(), title);
addToDrawer(nav);
}
}Open http://localhost:8080/hello: there is a header with a "hamburger" button and the name on top and a two-item menu on the left. Click "Draft" — only the central part changes, and the menu item is highlighted as active.
Parts of AppLayout
| Method or class | What it does |
|---|---|
addToNavbar(...) | Puts components into the header |
addToDrawer(...) | Puts components into the sliding side panel |
DrawerToggle | A button that hides and shows the panel |
SideNav, SideNavItem | The navigation menu; an item knows its view and highlights itself |
setPrimarySection(Section.DRAWER) | Full-height panel, header to the right of it |
On a narrow phone screen the panel collapses by itself and opens with the DrawerToggle button.
How a view gets into the layout
The @Layout annotation makes the class the default layout: all views with @Route are shown inside it automatically. If a view must not be inside the frame (a login page, for example), switch it off:
// src/main/java/com/example/blog/views/HelloView.java (fragment)
@Route(value = "hello", autoLayout = false)
public class HelloView extends VerticalLayout {Now /hello opens without the header and menu.
The second way is to name the layout on each view: @Route(value = "draft", layout = MainLayout.class). You will see it in older projects; with @Layout you do not need it.
Menu items with submenus
A SideNavItem can contain nested items, which gives an expandable group:
// src/main/java/com/example/blog/views/MainLayout.java (part of the constructor)
SideNavItem content = new SideNavItem("Content");
content.addItem(new SideNavItem("Draft", DraftView.class));
nav.addItem(content);The menu gets a "Content" item with an arrow, and "Draft" inside it.
Common mistake
The layout is written, but views show without it. Check two things: the layout class has @Layout, and the view does not have autoLayout = false. Another cause is a layout that does not extend AppLayout or another class implementing RouterLayout: then Vaadin does not know where to put the view and reports an error at startup.