Java Layout

Willemers Informatik-Ecke

Was ist ein Layout?

Ein Layout legt fest, in welcher Anordnung Kontrollelemente in ihre Container gesetzt werden. Die meisten Layouts wurden bereits in der AWT verwendet und es gibt keinen Grund, warum sie nicht auch bei Swing eingesetzt werden sollten.

Ein Layout wird mit der Funktion setLayout dem Container zugeordnet. Die Kontrollelemente werden dann per add-Funktion in das Layout gesteckt.

FlowLayout

Es werden alle Elemente von links nach rechts bis zum rechten Rand aufgefüllt und dann wird quasi zeilenweise nach unten gegangen. Das folgende Beispiel zeigt dies anhand einiger Buttons.
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.FlowLayout;

public class TestFlow extends JFrame {

    TestFlow() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container pane = getContentPane();
        pane.setLayout(new FlowLayout());
        for (int i=0; i<12; i++) {
            pane.add(new JButton("Button " + i));
        }
        this.setSize(400, 300);
        this.setVisible(true);
    }

    public static void main(String[] args) {
       new TestFlow();
    }
}
Der Konstruktor von FlowLayout kann einen Parameter für die Ausrichtung erhalten. Dort können die Werte FlowLayout.LEADING, FlowLayout.CENTER oder FlowLayout.TRAILING verwendet werden. LEADING sorgt für eine Linksausrichtung, TRAILING für eine Orientierung am rechten Rand. CENTER ist der Defaultwert.

BorderLayout

Wie der Name schon vermuten läßt wird ein Rand um ein zentrales Element gelegt. Man hat dann eine Kopfzeile, eine Fußzeile, einen linken und einen rechten Rand.

Um die Benennung zu vereinfachen, werden die Bereiche analog zu einer Landkarte mit NORTH, SOUTH, EAST und WEST bezeichnet. Das mittlere Feld heißt CENTER. Da diese Konstanten von der Klasse BorderLayout definiert werden, muss deren Name voranstehen. In welchem Feld die Kontrollelemente positioniert werden, wird durch beim Aufruf der Methode add durch den ersten Parameter angegeben.

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.BorderLayout;

public class TestBorder extends JFrame {

    TestBorder() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(400, 300);
        Container pane = getContentPane();
        pane.setLayout(new BorderLayout());
        pane.add(BorderLayout.NORTH, new JButton("Oben"));
        pane.add(BorderLayout.SOUTH, new JButton("Unten"));
        pane.add(BorderLayout.WEST, new JButton("Links"));
        pane.add(BorderLayout.EAST, new JButton("Rechts"));
        pane.add(BorderLayout.CENTER, new JButton("Mitte"));
        this.setVisible(true);
    }

    public static void main(String[] args) {
       new TestBorder();
    }
}

GridLayout

Das Grid legt ein Gitter an. Im Konstruktor wird die Zahl der Zeilen und der Spalten festgelegt. Durch Hinzufügen (add) werden die Elemente der Reihenfolge nach ins Grid gelegt, und zwar mit der ersten Zeile beginnend von links nach rechts.

Das GridLayout bietet sich an, wenn die anzuordnenden Elemente gleichartig sind.

Die Dimension des Grids wird im Konstruktor vorgegeben. Der erste Parameter legt die Anzahl der Zeilen, der zweite die Anzahl der Spalten fest.

Die Elemente werden einfach wie gehabt eingefügt. Dabei werden die Felder von links nach rechts und dann von oben nach unten aufgefüllt.

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.GridLayout;

public class TestGrid extends JFrame {

    TestGrid() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container pane = getContentPane();
        pane.setLayout(new GridLayout(6,2));
        for (int i=0; i<12; i++) {
            pane.add(new JButton("Button " + i));
        }
        pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
       new TestGrid();
    }
}

GridBagLayout

In der Praxis werden Elemente etwas komplexer angeordnet, als das bisher gezeigt wurde. Mit dem GridBagLayout sind auch komplexere Aufbauten möglich. Als Beispiel verwenden wir die folgende Anordnung:
+------+                +------+
+------+                |      |
        +------+        |      |
        +------+        +------+
                +------+
                +------+
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Container;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;

public class TestGridBag extends JFrame {

    TestGridBag() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagLayout gbLayout = new GridBagLayout();
        GridBagConstraints gbConstraints = new GridBagConstraints();
        Container pane = getContentPane();
        pane.setLayout(gbLayout);
        gbConstraints.fill = GridBagConstraints.BOTH;
        gbConstraints.weightx = 1.0;
        for (int i=0; i<3; i++) {
            JButton button = new JButton("Button" + i);
            gbLayout.setConstraints(button, gbConstraints);
            pane.add(button);
        }
        pack();
        this.setVisible(true);
    }

    public static void main(String[] args) {
       new TestGridBag();
    }
}
Die Attribute von GridBagConstraints
  • gridx
    Angabe der x-Position des Gitterelements.
  • gridy
    Angabe der y-Position des Gitterelements.
  • gridwidth
    Anzahl der belegten Gitterelemente in x-Richtung. Wird das Attribut mit GridBagConstraints.REMAINDER belegt, werden alle Gitterelemente bis zum rechten Rand des Containers belegt.
  • gridheight
    Anzahl der belegten Gitterelemente in y-Richtung. Wird das Attribut mit GridBagConstraints.REMAINDER belegt, werden alle Gitterelemente bis zum unteren Rand des Containers belegt.
  • weightx
    Ist in x-Richtung mehr Platz vorhanden, als das Kontrollelement benötigt, wird dieser nach der Gewichtung der nebeneinanderstehenden Elemente verteilt. Eingetragen wird ein Fließkommawert zwischen 0 und 1.
  • weighty
    Ist in y-Richtung mehr Platz vorhanden, als das Kontrollelement benötigt, wird dieser nach der Gewichtung der untereinanderstehenden Elemente verteilt. Eingetragen wird ein Fließkommawert zwischen 0 und 1.
  • ipadx
    Die Anzahl der Pixels, die der Breite des Elements hinzugefügt werden. Sie werden links und rechts gerecht aufgeteilt.
  • ipady
    Die Anzahl der Pixels, die der Höhe des Elements hinzugefügt werden. Sie werden oben und unten gerecht aufgeteilt.
  • fill
    Steht dieser Wert wie standardmäßig auf GridBagConstraints.NONE, wird das Kontrollelement nur den Raum beanspruchen, den es minimal benötigt. Durch Belegung mit GridBagConstraints.HORIZONTAL wird der gesamte Platz, der horizontal zur Verfügung steht vom Kontrollelement eingenommen. Analog steht GridBagConstraints.VERTICAL für vertikal und GridBagConstraints.BOTH für eine Ausdehnung in beide Richtungen.
  • insets
    gbConstraints.insets = new Insets(2,2,2,2);
    
    sorgt dafür, dass um die Kontrollelemente in jeder Richtung ein Abstand von 2 Pixeln eingehalten wird.

BoxLayout

Das BoxLayout ist kein Erbstück aus AWT-Zeiten, sondern ist für Swing gemacht. Darum wird er auch nicht aus der AWT-Bibliothek importiert, sondern von Swing.
javax.swing.BoxLayout

\begin{verbatim}
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Container;
import javax.swing.BoxLayout;

public class ErsterSwing extends JFrame {

    ErsterSwing() {
        this.setSize(400, 300);
        Container pane = getContentPane(); 
        pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS)); 
        JLabel anton = new JLabel("Anton"); 
        JLabel berta = new JLabel("Berta"); 
        JLabel caesar = new JLabel("Caesar"); 
        pane.add(anton); 
        pane.add(berta); 
        pane.add(caesar); 
        this.setVisible(true);
    }

    public static void main(String[] args) {
       new ErsterSwing();
    }
}
BoxLayout.X_AXIS      von links nach rechts
BoxLayout.LINE_AXIS
BoxLayout.Y_AXIS      von oben nach unten
BoxLayout.PAGE_AXIS

Eigenes Layout ohne Layout-Manager

Wird setLayout mit dem Parameter null aufgerufen, ist gar kein Layout aktiv.
pane.setLayout(null);
Nun werden die Kontrollelemente einfach hinzugefügt und überdecken sich in diesem Augenblick. Anschließend werden die einzelnen Kontrollelemente über deren Methode setBounds positioniert:
button.setBounds(xPos, yPos, breite, hoehe);
Der Haken an dieser Methode ist, dass sich die Absolutpositionen nicht danach richten, welchen Platzbedarf die Kontrollelemente haben. Auf diese Weise kann es dazu führen, dass die Beschriftungen nicht mehr lesbar sind, weil beispielsweise der Benutzer übergrößere Zeichensätze verwendet.


Homepage - Java (C) Copyright 1999, 2000, 2011 Arnold Willemer