Teil 8: Aufbau der Anwendung III

Backend meets Frontend Reloaded: Vaadin Add-ons für das App Layout

Sven Ruppert

© Shutterstock / HelenField & bkf (modifiziert)

Im vorherigen Teil der Serie haben wir uns mit dem App-Layout von Vaadin beschäftigt. Für einfache Anwendungen ist das eine sehr gute Wahl. Diesmal wird es aber um Anforderungen gehen, die etwas umfangreicher sind als die Positionierung einer Menüleiste. Hierfür gibt es ein paar komfortablere Add-ons aus dem Vaadin Directory. Wir werden uns explizit das Add-on von Johannes Goebel ansehen.

Vorbereitungen

Wenn man auf der Suche nach Add-ons für Vaadin ist, sollte die Suche im offiziellen Vaadin Directory beginnen. Hier findet man allerlei Add-ons zu den unterschiedlichsten Fragestellungen und Anforderungen. Um Zugriff via Maven auf die dort gehosteten Add-ons zu bekommen, muss man in der pom.xml das spezifische Vaadin Repository angeben:

<repositories>
  <repository>
    <id>vaadin-addons</id>
    <url>http://maven.vaadin.com/vaadin-addons</url>
  </repository>
</repositories>

Nachdem Maven die neuen Koordinaten bekommen hat und die Gelegenheit hatte, das Repository zu scannen, stehen einem in der IDE die Informationen zur Verfügung, um zum Beispiel das hier besprochene Add-on zu verwenden bzw. erst einmal in der pom.xml zu deklarieren.

<dependency>
   <groupId>com.github.appreciated</groupId>
   <artifactId>app-layout-addon</artifactId>
   <version>2.1.0.alpha1</version>
</dependency>

Ich beziehe mich hier auf die angegebene Version 2.1.0.alpha1. Da sich das Add-on unter aktiver Entwicklung befindet, lohnt es sich nachzusehen, ob es mittlerweile schon ein weiteres Update und damit eine neuere Version gibt.

Das Layout

Das letzte Mal hatten wir die Menüpunkte an der oberen Seite im Layout eingebunden. Diesmal werden wir das Menü am Rand der linken Seite, von oben nach unten orientiert, positionieren. Das Grundgerüst, das hier zum Einsatz kommen wird, basiert auf der Komponente App Layout von Johannes Goebel. Die offizielle Beschreibung zu der Komponente befindet sich übrigens hier.

Kommen wir nun zur Implementierung. Im letzten Teil wurde eine Klasse mit dem Namen MainLayout erstellt. In dieser Klasse haben wir die Definitionen des Layouts platziert. Wenn alles sauber implementiert worden ist, sollte auch ausschließlich diese Klasse wieder zu editieren sein, um auf das neue Layout zu wechseln. Die Klasse MainLayout erbt diesmal von der Klasse AppLayoutRouterLayout. Wie auch in der vorherigen Version, ist in den Basisklassen das für das jeweilige Layout Spezifische, implementiert. Die Initialisierung erfolgt im aktuellen Beispiel innerhalb des Konstruktors.

W-JAX 2019 Java-Dossier für Software-Architekten

Kostenlos: 30+ Seiten Java-Wissen von Experten

Sie finden Artikel zu EnterpriseTales, Microservices, Req4Arcs, Java Core und Angular-Abenteuer von Experten wie Uwe Friedrichsen (codecentric AG), Arne Limburg (Open Knowledge), Manfred Steyer (SOFTWAREarchitekt.at) und vielen weiteren.

 

Das Grundgerüst

Der Ansatz in diesem Layout ist auch wieder basierend auf dem RouterLayout-Konzept von Flow. Wer hier ein wenig über die Grundprinzipien nachlesen möchte, dem empfehle ich die Dokumentation im Learning Center.

Das Grundgerüst wird in diesem Falle über spezialisierte Builder erzeugt und nach erfolgter Konfiguration mittels der Methode init(AppLayout applayout) der Basisimplementierung übergeben. Der Haupt-Builder befindet sich in der Klasse AppLayoutBuilder und die Methode get(...) liefert eine Instanz zurück. Der Parameter der Methode AppLayoutBuilder.get legt dazu das grundlegende Verhalten des Layouts fest. Zur Auswahl stehen derzeit:

  • LEFT
  • LEFT_RESPONSIVE
  • LEFT_HYBRID
  • LEFT_HYBRID_SMALL
  • LEFT_RESPONSIVE_HYBRID
  • LEFT_RESPONSIVE_HYBRID_NO_APP_BAR
  • LEFT_RESPONSIVE_HYBRID_OVERLAY_NO_APP_BAR
  • LEFT_OVERLAY
  • LEFT_RESPONSIVE_OVERLAY
  • LEFT_RESPONSIVE_OVERLAY_NO_APP_BAR
  • LEFT_RESPONSIVE_SMALL
  • LEFT_RESPONSIVE_SMALL_NO_APP_BAR
  • TOP
  • TOP_LARGE

Anhand der Namen kann man schon erkennen, dass es zwei Hauptgruppen gibt. Die eine Gruppe hat das Menü auf der linken Seite, die andere Gruppe hat die Menüpunkte am oberen Rand. In diesem Bespiel verwende ich das Verhalten mit dem Namen LEFT_RESPONSIVE_HYBRID:

 public MainLayout() {
   Image img = new Image(
     new StreamResource(LOGO_PNG, 
                        () -> MainLayout.class.getResourceAsStream("/" + LOGO_PNG)),
     "Vaadin Logo"
   );
 
   //app layout specific
   img.setHeight("var(--app-layout-menu-button-height)");
 
   AppLayout appLayout = AppLayoutBuilder
       .get(Behaviour.LEFT_RESPONSIVE_HYBRID)
       .withTitle(getTranslation(TITLE))
       .withIconComponent(img)
       .withAppMenu(appMenu())
       .build();
 
   init(appLayout);
 }

Die restlichen Methoden des Builders sind recht selbsterklärend. Eine Besonderheit gibt es noch, wenn man ein Logo setzen möchte. Verwendet man die Methode mit der Signatur, die eine Instanz der Klasse Image akzeptiert, muss man das Attribut Height auf den Wert setzen, der durch var(--app-layout-menu-button-height) definiert wird.

Das Menü

Die Definition von einem Menü ist hier noch nicht erkennbar und ist durch den Methodenaufruf appMenu() bisher verborgen worden.

private Component appMenu() {
  return LeftAppMenuBuilder
      .get()
      .add(getTranslation(ITM_DASHBOARD), DASHBOARD.create(), DashboardView.class)
      .add(getTranslation(ITM_PROFILE), USER.create(), ProfileView.class)
      .add(getTranslation(ITM_TRENDS), TRENDING_UP.create(), TrendsView.class)
      .add(new LeftClickableItem(getTranslation(ITM_LOGOUT), SIGN_OUT.create(), e -> {
        UI            ui      = UI.getCurrent();
        VaadinSession session = ui.getSession();
        session.setAttribute(SecurityService.User.class, null);
        session.close();
        ui.navigate(MainView.class);
      }))
      .build();
}

Auch in diesem Fall gibt es für das Menü auf der linken Seite einen entsprechenden Builder. Der Klassenname lautet LeftAppMenuBuilder. Bei der ersten Verwendung, in der wir ein semantisches Äquivalent zu dem Beispiel aus dem letzten Teil erzeugen wollen, lediglich die Methode add relevant. Zum Einsatz kommen zwei Versionen der Methode: Die erste Version erzeugt Navigationsziele, die sich aus denselben Elementen erzeugen lassen, wie im vorherigen Teil. Gemeint ist ein Icon, eine Beschreibung, die mittels I18N übersetzt wird, und ein Navigationsziel. Letzteres wird durch die Angabe der Klasse vorgenommen, die über eine Annotation vom Typ Route verfügt.

Die zweite Version bekommt eine Instanz der Klasse LeftClickableItem übergeben. Die notwendigen Angaben unterscheiden sich lediglich in dem letzten Parameter. Anstelle eines Navigationsziels wird hier eine Aktion definiert, die ausgeführt werden soll. Hier ist es ein Abmelden des angemeldeten Benutzers und ein damit einhergehendes Beenden der Session. Um nun das Layout zu verwenden, muss man an den beteiligten Views in der Annotation @Route das Attribut layout mit der Klasse MainLayout belegen.

Fazit

Das hier verwendete App Layout hat noch einge weitere Eigenschaften, die hier nicht erwähnt worden sind. Um tiefer einzusteigen, lohnt sich ein Blick in die Beispiele des Projektes, die sehr ausführlich sind. Hervorheben möchte ich auch, dass es sich um ein responsives Layout handelt, was recht gut mit den verschiedenen Endgeräten wie Desktop, Tablet oder Mobiltelefon harmoniert.

Das Beispiel zu diesem Teil ist wie immer auf GitHub zu finden.

Wer Fragen und Anmerkungen hat, meldet sich am besten per Twitter an @SvenRuppert oder direkt per Mail an sven.ruppert@gmail.com

Happy Coding!

Geschrieben von
Sven Ruppert
Sven Ruppert
Sven Ruppert arbeitet seit 1996 mit Java und ist Developer Advocate bei Vaadin. In seiner Freizeit spricht er auf internationalen und nationalen Konferenzen, schreibt für IT-Magazine und für Tech-Portale. Twitter: @SvenRuppert
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
4000
  Subscribe  
Benachrichtige mich zu: