Professionell von Beginn an!

Java-Tutorial für Einsteiger – Teil 4: Moderne Benutzeroberflächen in Java

Dr. Veikko Krypczyk, Olena Bochkor

(c) Shutterstock / Curioso

In diesem mehrteiligen Tutorial präsentieren wir Ihnen eine Einführung in Java für anspruchsvolle Einsteiger, die daran interessiert sind, Java-Anwendungen jenseits des “Hello-World” zu programmieren. Haben wir uns im dritten Teil mit der Objektorientierten Programmierweise beschäftigt, geht es nun um die Umsetzung von Benutzeroberflächen mit Java.

Ansprechend, nutzerorientiert und technisch sauber

Die Adjektive der Überschrift beschreiben schon sehr gut die heutigen Anforderungen an eine grafische Benutzeroberfläche. Mit Java können Desktop-Applikationen für alle gängigen Betriebssysteme erstellt werden. Diese sind umfassend in die Systemumgebungen integriert. Dieser vierte Teil unseres Java-Tutorials beschreibt die technische Vorgehensweise bei der Gestaltung des User-Interfaces.

 

Java-Tutorial für Einsteiger: Professionell von Beginn an!

java tutorialDieses Java-Tutorial führt Sie Schritt für Schritt in die Programmierung mit Java ein. Anhand einer durchgängigen GUI-Beispielanwendung werden die wichtigsten Programmierkonzepte, Sprachkonstrukte und Werkzeuge in einem professionellen Setting vorgestellt.

Java-Tutorial Teil 4: Moderne Benutzeroberflächen in Java

Nahezu alle modernen Programme werden heute über grafische Benutzeroberflächen bedient. Komfortabel in der Handhabung, ansprechend im Design und orientiert an der Aufgabenstellung des Kunden sind diese zu gestalten. Java bietet alle Möglichkeiten, zeitgemäße grafische Benutzeroberflächen zu realisieren. In diesem Teil werden wir uns mit den Grundlagen der User-Interface (UI)-Gestaltung in Java auseinandersetzen. Damit es nicht bei der Theorie bleibt, können Sie die Umsetzung an unserem Beispiel WordCloud, verfügbar über GitHub, nachvollziehen.

WordPress im Videotutorial

Im entwickler.tutorial Einstieg in WordPress erklärt Vladimir Simović, Blogger, Autor, Unternehmer und Experte für WordPress und CSS, die Grundlagen von WordPress – von der Installation bis hin zu Plug-ins und Themes.

UI in Java

Java bietet von Hause aus nahezu alle Voraussetzungen, um die o.g. Anforderungen an ein UI zu erfüllen. Dabei muss der große Vorteil von Java nochmals hervorgehoben werden: Java ist plattformübergreifend einsetzbar. Sie müssen sich nicht mit der Gestaltung der Benutzeroberflächen separat für Windows, Mac OS oder Linux „herumschlagen“. Mit Java entwickeln Sie eine generische Oberfläche, welche auf allen Systemen läuft.

Die Java-Plattform bietet eine große Zahl an Bausteinen, die man zu dem gewünschten UI zusammenfügen kann. Dabei folgt der Aufbau des UI nach dem Baukastenprinzip. Vorgefertigte Komponenten werden miteinander verschachtelt und kombiniert. Die Komponenten sind dabei einzelne Klassen, welche Bestandteil einer umfassenden Klassenbibliothek für die UI-Gestaltung sind. Folgende Gruppen lassen sich bilden:

  • Grundkomponenten: Diese umfassen einfache Oberflächenelemente wie Labels, Buttons und Checkboxen.
  • Container: Es handelt sich um Komponenten, welche selbst wieder andere Komponenten, zum Beispiel Buttons und Labels aufnehmen können.
  • Layout-Manager: Diese bestimmen die Anordnung der anderen Komponenten im Fenster. Da Java-Programme auf den verschiedensten Hard- und Softwareplattformen laufen, spielt die relative und dynamische Anordnung der Elemente eine besonders große Rolle. Dabei bestimmt das Programm die endgültige Position der Komponenten automatisch u.a. anhand der Eigenschaften Fenstergröße, Bildschirmauflösung und eingestellter Schriftgröße.
  • Ereignisse und Listener: Man unterscheidet passive Komponenten, welche lediglich Informationen auf der Oberfläche anzeigen, wie zum Beispiel Labels. Andere Komponenten, wie Buttons oder Checkboxen, interagieren mit dem Benutzer. Dabei muss auf bestimmte Ereignisse, zum Beispiel ein Mausklick oder eine Auswahloperation, reagiert werden.

Die Klassen der UI-Komponenten finden sich in den Paketen java.awt und javax.swing, wobei die Swing-Klassen die AWT-Klassen bezüglich der Gruppen Grundkomponenten und Container ersetzen. Die AWT-Klassen der beiden letztgenannten Gruppen werden weiterverwendet. Blicken wir deshalb auf die Klassenhierarchie, welche auszugsweise in Abbildung 1 dargestellt ist.

Abbildung_1

Abbildung 1: Die AWT- und Swing-Klassen-Hierarchie [1].

Auf oberster Ebene steht die Klasse Component. Von dieser Klasse werden alle weiteren Klassen abgeleitet. Man sieht beispielsweise ebenfalls, dass es zu Klasse Label aus java.awt eine Entsprechung JLabel in javax.swing gibt. Die Swing-Bibliothek ist noch weitaus umfangreicher, wie das Klassendiagramm in Abbildung 2 zeigt.

Abbildung_2

Abbildung 2: Auszug aus der Swing-Klassenbibliothek [2].

Die Swing-Komponenten sind eine Erweiterung der AWT-Komponenten. Zum grundsätzlichen Unterschied lesen Sie bitte auch den Textkasten AWT- vs. Swing-Klassenbibliothek.

AWT- vs. Swing-Klassenbibliothek
Ein wichtiges Merkmal beim Aufbau des UI ist die Plattformunabhängigkeit. Das Abstract Window Toolkit (AWT) ist so ausgelegt, dass alle Elemente des UI durch das Betriebssystem zur Verfügung gestellt werden. Damit ist AWT durch den kleinsten gemeinsamen Nenner aller Betriebssysteme beschränkt. Man bezeichnet diese Vorgehensweise als Peer-Ansatz, weil die AWT-Komponenten alle Aktionen an plattformspezifische GUI-Objekte (Peers) weiterreichen. Auf unterschiedlichen Betriebssystemen sehen daher Java-Anwendungen, welche auf der Basis von AWT erstellt werden, unterschiedlich aus. AWT-Komponenten werden als schwergewichtig (heavyweight) bezeichnet. Die Swing-Klassen basieren auf einen anderen Ansatz. Sie sind fast alle selbst in Java programmiert, damit lichtgewichtig (lightweigh) und benutzen nur da wo es notwendig ist (Top-Level-Container), plattformspezifische Funktionen. Das Design des UI kann unabhängig vom Betriebssystem gestaltet werden und es ist sogar eine Anpassung zur Laufzeit möglich. Programme auf der Basis von Swing sehen daher auf allen Betriebssystemen gleich aus.

Frame und JFrame

Für Programme mit einer grafischen Oberfläche wird auf oberster Ebene ein Basiscontainer (Top-Level-Container) benötigt. Dieser stellt das Hauptfenster mit Titelleiste, Icons und Systemmenü dar. Verwendet man das AWT-Toolkit, wird ein solches Fenster von der Klasse Frame abgeleitet. Im Regelfall verwendet man heute jedoch die Swing-Bibliothek. Die entsprechende Klasse lautet hier JFrame. Um das eigene Fenster nach seinen Wünschen anzupassen, ist dieses somit von der Klasse JFrame abzuleiten. Der Quellcode gestaltet sich dann wie folgt:

public class MainFrame extends javax.swing.JFrame{
   …
}

Wenn Sie eine integrierte Entwicklungsumgebung für die Programmerstellung verwenden, brauchen Sie diese Quellcodezeilen nicht selbst zu schreiben. Mit dem Erzeugen eines neuen Fensters (JFrame) wird er automatisch generiert. Beim Start der Applikation muss festgelegt werden, welches Fenster initial angezeigt werden soll. Dazu muss ein Objekt des betreffenden Frames in der Methode main erstellt werden (Listing 1).

    public static void main(String[] args) {
        // TODO code application logic here
        MainFrame frame=new MainFrame();
        frame.setTitle("Word Cloud");
        frame.setSize(1000, 620);
        frame.setResizable(false);
        frame.setLocation(50, 50);
        frame.setVisible(true);
    }

Container

Container (Klasse Container) enthalten anderen Komponenten. Eine Komponente, die auf dieser Klasse basiert, ist zum Beispiel die Klasse JFrame. JFrame dient als oberstes Element einer fensterbasierten Anwendung. Die Klasse Container stellt daher Methoden zur Verfügung, welche das Einfügen, Verwalten und Entfernen von Komponenten ermöglichen (Tabelle 1). Diese Klassenelemente werden an die untergeordneten Klassen vererbt.

Methode Beschreibung
public Component add(Component comp) Fügt die Komponente comp hinzu.
public Component add(Component comp, int index) Fügt die Komponente comp an der Stelle index hinzu.
public Component[] getComponents() Gibt eine Liste aller Komponenten zurück.
public void remove(Component comp) Die Komponente comp wird aus dem Container entfernt.
public void setLayout(LayoutManager mgr) Definiert das Layout des Containers.

Tabelle 1: Wichtige Methoden der Klasse Container in Bezug auf die Verwaltung von Komponenten.

 

In welcher Weise die Komponenten innerhalb eines Containers angeordnet werden, ergibt sich durch den zugewiesenen Layout-Manager (siehe letzte Methode von Tabelle 1). Der Regelfall ist die automatische Platzierung, unter Beachtung der gewählten Vorgaben. Wir betrachten das Thema im kommenden Anschnitt.

Layout-Manager

Ein Layout-Manager legt die Anordnung der untergeordneten Komponenten in einem Container fest. Basis für einen Layout-Manager ist das gleichnamige Interface LayoutManager. Dieses Interface definiert Methoden, welche für die Anordnung der Komponenten verantwortlich sind. Das Interface selbst wird von vielen Container-Komponenten implementiert, u.a. von der Klasse JFrame. Verfügbare Layout-Manager sind:

  • FlowLayout: Anordnung der Komponenten von links nach rechts.
  • BoxLayout: Ordnet Komponenten horizontal oder vertikal an.
  • GridLayout: Setzt Komponenten in ein Raster, wobei jedes Element die gleichen Abmessungen hat.
  • BorderLayout: Platziert die Komponenten in die vier Himmelsrichtungen oder in der Mitte des Containers.
  • GridBagLayout: Erweiterung von GridLayout.
  • CardLayout: Verwaltet Komponenten wie auf einem Stapel, sodass nur eine Komponente sichtbar ist.
  • SpringLayout: Berücksichtigt die Abhängigkeiten der Kanten von den Komponenten.
  • GroupLayout: Für UI-Builder eine gute Wahl
  • NullLayout: Hier wird kein LayoutManager verwendet, die Anordnung der Komponenten erfolgt in absoluter Positionierung. Dieses ist grundsätzlich nicht empfehlenswert. Ausnahmsweise ist es für schnelle Prototypen akzeptabel oder wenn man sicherstellen kann, dass die Anwendung auf identischen Zielgeräten bei gleichen Einstellungen (Auflösung, Schriftgröße usw.) läuft.

Die am meisten verwendeten Layout-Manager sind FlowLayout, BorderLayout und GridLayout. Beispielhaft betrachten wir den FlowLayout– und den BorderLayout-Manager etwas näher: Der FlowLayout-Manager ordnet die der Oberfläche zugewiesenen Komponenten der Reihe nach in einer Zeile an, bis der Platz nicht mehr ausreicht, eine weitere Komponente darzustellen. Die verbliebenen Komponenten werden nach dem gleichen Prinzip in der folgenden Zeile verschoben. Die Reihenfolge, in der die Elemente platziert werden, entspricht der Reihenfolge ihrer Registrierung. Dieser Layout-Manager bietet die Möglichkeit festzulegen, von welcher Seite aus eine Zeile aufgebaut wird (Property: align) und wie viele Pixel der horizontale (Property: hgap) und vertikale (Property: vgap) Abstand der einzelnen Komponenten zueinander betragen soll.

Am besten versteht man es mit Hilfe eines kleinen Beispiels: Der Quelltext in Listing 2 ordnet sechs Buttons mit Hilfe des FlowLayout-Managers an. Dazu wird zunächst der Layout-Manager zugewiesen (Zeile 10), die Buttons werden einzeln erzeugt und als Komponente in die ContentPane eingefügt (Zeilen 12-13). Die Methode pack() sorgt am Ende für die automatisch richtige Fenstergröße beim Systemstart.

private void initComponents() {
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());

        jButton1.setText("jButton1");
        getContentPane().add(jButton1);

        jButton2.setText("jButton2");
        getContentPane().add(jButton2);

        jButton3.setText("jButton3");
        getContentPane().add(jButton3);

        jButton4.setText("jButton4");
        getContentPane().add(jButton4);

        jButton5.setText("jButton5");
        getContentPane().add(jButton5);

        jButton6.setText("jButton6");
        getContentPane().add(jButton6);

        pack();
    }

Starten wir die Anwendung, werden – je nach Größe des Fensters – die Buttons nebeneinander angeordnet und bei Bedarf in die nächste Zeile umgebrochen. Das Ergebnis ist in den Abbildungen 3 und 4 zu sehen.

Abbildung_3

Abbildung 3: Alle Komponenten werden bei Einsatz des FlowLayout-Manager nebeneinander angeordnet.

Abbildung_4

Abbildung 4: Reicht der Platz am Rand nicht aus, erfolgt der Umbruch in die nächste Zeile.

Ebenso ist zu definieren, wie das Fenster reagieren soll, wenn der Anwender auf den Close-Button in der Titelleiste klickt. Dazu dient die folgende Quellcodezeile:

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

Der Parameter in Klammern gibt das Verhalten an. Die Optionen sind in Tabelle 2 dargestellt. Wird das Hauptfenster einer Applikation geschlossen, so muss das Programm beendet werden. Der Wert des Parameters lautet daher in diesem Fall EXIT_ON_CLOSE.

Konstante Beschreibung
DO_NOTHING_ON_CLOSE Keine Aktion, d.h. das Fenster schließt auch nicht. Es schließt erst, wenn das übergeordnete Fenster (falls ein solches gibt) geschlossen wird.
HIDE_ON_CLOSE Der Frame wird lediglich unsichtbar, er verbleibt aber im Speicher und kann wieder sichtbar gemacht werden.
DISPOSE_ON_CLOSE Der Frame wird geschlossen und aus dem Speicher entfernt.
EXIT_ON_CLOSE Schließt den Frame und beendet das Programm mit System.exit(0)

Tabelle 2: Mögliche Reaktionen auf das Schließen eines Fensters [2].

Mit Hilfe einer kleineren Test-Applikation kann man leicht die Wirkung der unterschiedlichen Layout-Manager studieren. Stellen wir das eben vorgestellte Beispiel auf das BorderLayout um, ergibt sich die Darstellung gemäß Abbildung 5.

Abbildung_5

Abbildung 5: Das gleiche Beispiel mit Hilfe des BorderLayouts.

Der zugehörige Quellcode (Änderung in Zeile 12-13) ist in Listing 3 zu sehen.

private void initComponents() {

        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        getContentPane().add(jButton1, java.awt.BorderLayout.CENTER);

        jButton2.setText("jButton2");
        getContentPane().add(jButton2, java.awt.BorderLayout.PAGE_START);

        jButton3.setText("jButton3");
        getContentPane().add(jButton3, java.awt.BorderLayout.PAGE_END);

        jButton4.setText("jButton4");
        getContentPane().add(jButton4, java.awt.BorderLayout.LINE_END);

        jButton5.setText("jButton5");
        getContentPane().add(jButton5, java.awt.BorderLayout.LINE_START);

        jButton6.setText("jButton6");
        getContentPane().add(jButton6, java.awt.BorderLayout.CENTER);

        pack();
    }

Dieser Layout-Manager ist Standard für JFrame-Container und braucht daher nicht extra definiert werden. Die einzelnen Komponenten werden wieder erstellt und in Bezug auf die Ausrichtung wie gewünscht platziert.

Container können mit Hilfe von Layout-Managern ineinander geschachtelt werden. Damit sind nahezu beliebig komplexe Layouts möglich, und man kann fast jede Anordnung der Komponenten auf der Oberfläche erreichen, ohne die Komponenten absolut zu positionieren. Es bedeutet aber auch, dass es nicht nur eine Lösung für die technische Umsetzung des gewünschten Layouts gibt. Die Kunst besteht darin, einen möglichst einfachen Ansatz zu erarbeiten. Anderseits hat jeder Entwickler auch seine individuelle Vorgehensweise, und verschiedene UI-Builder verwenden die Layout-Manager in unterschiedlicher Priorität. Fazit: Mehrere Wege führen zum Ziel!

UI-Builder

Muss man das alles mit der Hand codieren? Ja und Nein! Sie können das komplette UI im Quellcode erstellen. Man kann sich aber auch helfen lassen. Dazu benutzen wir eine integrierte Entwicklungsumgebung. Diese bieten i.d.R. gut funktionierende UI-Builder. Mit deren Hilfe kann man das UI komplett oder teilweise erstellen. Je nach Entwicklungsumgebung ist die Funktionsweise etwas unterschiedlich, aber ähnlich im Ablauf. Dazu wird das Formular grafisch dargestellt und man platziert darauf die Komponenten. Die Komponenten entnimmt man üblicherweise aus einer Toolpalette und verschiebt sie mittels Drag-& Drop-Operationen auf das Formular. Im Eigenschaften-Editor können die wichtigsten Werte der Eigenschaften einer Komponente modifiziert werden.

Die Arbeit mit einem solchen UI-Builder muss man üben. Mit der Zeit steigt die Vertrautheit und Effektivität. Im Hintergrund wird der zugehörige Code erstellt. Je nach UI-Builder kann man diesen noch manuell anpassen, oder er ist bereits einsatzfähig. Die IDE NetBeans (Abbildung 6) enthält einen sehr guten UI-Builder, deren leichte Handhabung auch den Ausschlag für die Auswahl dieser Entwicklungsumgebung gegeben hat.

Abbildung_6

Abbildung 6: NetBeans enthält einen leistungsfähigen UI-Builder.

Das UI des WordCloud-Managers

Soweit die Theorie, kommen wir nun zu unserem konkreten Beispiel. Bitte erinnern Sie sich an den Entwurf für das UI (Teil 1). Dieser Entwurf ist erneut in Abbildung 7 zu sehen.

Abbildung_7

Abbildung 7: Entwurf des UI.

Nun wollen wir die Benutzeroberfläche in Java umsetzen. Auf oberster Ebene fügen wir dem Projekt ein neues Formular (JRame) hinzu. Ein JFrame verwendet standardmäßig das BorderLayout (Abbildung 8).

Abbildung_8

Abbildung 8: Der Layout-Manager kann komfortabel über das Kontextmenü angepasst werden.

Oben (Top) platzieren wir eine Toolbar (JToolBar), auf welcher später Symbole hinzugefügt werden. Ebenso werden zwei weitere Panel (JPanel) auf die Oberfläche gezogen. Das Panel am rechten Rand dient der Anzeige der Wörter und der Interaktion mit dem Benutzer. Das Panel im Zentrum nimmt ein DrawingPanel auf, welches als Zeichenfläche dient. Am besten Sie „untersuchen“ das UI interaktiv in NetBeans. Im Navigator am linken Rand kann man die Struktur betrachten. Das Design des UI erfordert Übung und auch ein wenig Probieren. Gelegentlich muss man Zwischenlösungen verwerfen, wenn sie nicht ansprechend aussehen. Den ersten Entwurf des UI in Java sehen Sie in Abbildung 9, wobei das Programm gestartet wurde.

Abbildung_9

Abbildung 9: Der erste Entwurf des UI unseres Programms WordCloud in Java.

Gestalten Sie das Formular nach Ihren Vorstellungen, experimentieren Sie mit den Werten für die Eigenschaften (zum Beispiel Farben, Schriftgrößen) und verändern Sie die Layout-Manager! Sollte es am Anfang nicht gelingen, kein Problem! Machen Sie es wieder rückgängig, dank Versionsverwaltung ist das kein Problem.

Zusammenfassung und Ausblick

Wir sind am Ende des vierten Teiles unseres Einstiegskurses in die Programmiersprache Java angekommen. Schade eigentlich, sind wir doch mit unserem Programm (WordCloud) oder Sie mit Ihrer eigenen Idee gerade mittendrin. Sie haben jetzt hoffentlich das Rüstzeug, um weiter einzusteigen und neue Ideen umzusetzen. Java ist allgegenwärtig. Nicht nur auf dem Desktop, auch im mobilen Bereich wird in Java programmiert. Apps für Smartphones und Tablets mit Android als Systemumgebung werden in Java entwickelt. Zwar werden die Oberfläche und die Systemfunktionen der mobilen Geräte mit Hilfe spezieller Programmbibliotheken angesprochen, aber es bleibt Java.

Wie kommen Sie am besten weiter? Suchen Sie sich ein konkretes Projekt und starten Sie! Mit Sicherheit kommen einige Stolpersteine, und viele Themen haben wir in unserem Kurs nicht angesprochen. Jedoch gilt: Für fast alle Fragen findet sich im Netz dank einer aktiven Community eine brauchbare Lösung.

Hier geht’s zum Teil 5 des Tutorials: User Interfaces mit JavaFX

Verwandte Themen:

Geschrieben von
Dr. Veikko Krypczyk
Dr. Veikko Krypczyk
Dr. Veikko Krypczyk studierte und promovierte in Betriebswirtschaftslehre mit dem Schwerpunkt Wirtschaftsinformatik. Er ist Entwickler und Fachautor. Aktuell beschäftigt er sich mit der App-Programmierung für Windows Phone und Android.
Olena Bochkor
Olena Bochkor
Olena Bochkor studierte Betriebswirtschaftslehre u. a. mit dem Schwerpunkt Wirtschaftsinformatik. Weitere Informationen zu diesen und anderen Themen der IT finden Sie unter http://it-fachartikel.de.
Kommentare

Hinterlasse einen Kommentar

4 Kommentare auf "Java-Tutorial für Einsteiger – Teil 4: Moderne Benutzeroberflächen in Java"

avatar
400
  Subscribe  
Benachrichtige mich zu:
TestP
Gast

Mal ehrlich, wenn ich ein Programmiereinsteiger wäre dann könnte ich mit dem Kurs absolut nichts anfangen. Das Ding ist vielleicht eine nette Übersicht was mit Java so alles möglich ist. Aber ein Kurs ist das IMHO überhaupt nicht.

Grüße

Milchreis
Gast

Ich finde das Tutorial nicht schlecht, aber wäre es nicht zeitgemäß ein Tutorial über JavaFX und den SceneBuilder zu schreiben?
Hier hat sich dich einiges getan, was durchaus auch für Einsteiger geeignet ist.

Ma
Gast

Als ich die Überschrift las, dachte ich erst an ein JavaFX Tutorial. Leider wurde ich ziemlich enttäuscht. Mit modern hat das nur sehr sehr wenig zu tun und ich finde es ehrlich gesagt auch sehr schade, dass man hier nicht auf Aktuelles setzt, sondern die Zielgruppe die hier angesprochen werden soll bewusst an veraltete Technologien heranführt.

Karsten Lentzsch
Gast

Dieses Tutorial breitet mal wieder die schlimmsten Anfängerfehler bei der Java-Desktop-Entwicklung aus – egal ob Swing oder JavaFX. JFrame erweitert man genauso häufig, wie man HashMap erweitert; man nutzt die Klassen einfach. Die vorgestellten Layouts sind unbrauchbar dazu aber unnötig kompliziert. Die Komponenten sollte man anders erzeugen und konfigurieren. Und visuelle Editoren werden vorgestellt ohne deren Probleme mindestens anzureißen.

Wer diesem Tutorial folgt, wird mit ungünstiger Implementierung bei genau dem Gurkendesign enden, für das der Java-Desktop so lange falsch kritisiert worden ist.