GridBagLayout

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Das GridBagLayout

Das GridBagLayout ist der mächtigste und für Einsteiger komplizierteste LayoutManager aus dem Java AWT Package. Er dient dem Layouten von Benutzeroberflächen von Java-Anwendungen in Form eines Rasters (Grid).
Mit diesem LayoutManager bleiben kaum Wünsche für die Anordnung von Komponenten in einer Benutzeroberfläche offen.

Ein erstes einfaches Beispiel

Folgender Javacode soll einen kurzen Einstieg zeigen und für weitere Abschnitte als Ausgangscode dienen <code=java> import java.awt.*; import static java.awt.GridBagConstraints.*; import javax.swing.*;

public class GridBagLayoutExample extends JPanel {

   // Alle constraint Felder, nur wegen der Klarheit:
   private int gridx, gridy, gridwidth, gridheight, fill, anchor, ipadx, ipady;
   private double weightx, weighty;
   private Insets insets;
   public GridBagLayoutExample() {
       setLayout(new GridBagLayout());
       example();
   }
   /*
   Obwohl die Koordinaten eigentlich bei 0 beginnen, haben wir der Klarheit halber
   in diesem Beispiel die Zeile 0 und die Spalte 0 nicht belegt.
   In diesem Fall schreiben wir also einfach gridx=1 für die erste Spalte
   und gridy=1 für die erste Zeile.
    */
   private void example() {
       addGB(new JButton("Norden"), gridx = 2, gridy = 1);
       addGB(new JButton("Westen"), gridx = 1, gridy = 2);
       addGB(new JButton("Zentrum"), gridx = 2, gridy = 2);
       addGB(new JButton("Osten"), gridx = 3, gridy = 2);
       addGB(new JButton("Süden"), gridx = 2, gridy = 3);
   }
   //Bequemlichkeitsmethoden für das Hinzufügen von Komponenten mit den benötigten GridBagConstraints:
   private void addGB(Component component, int gridx, int gridy) {
       addGB(component, gridx, gridy, 1, 1, NONE, 0.0, 0.0, CENTER, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, int gridwidth) {
       addGB(component, gridx, gridy, gridwidth, 1, NONE, 0.0, 0.0, CENTER, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, int gridwidth, int gridheight) {
       addGB(component, gridx, gridy, gridwidth, gridheight, NONE, 0.0, 0.0, CENTER, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, int gridwidth, int gridheight, int fill) {
       addGB(component, gridx, gridy, gridwidth, gridheight, fill, 0.0, 0.0, CENTER, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, double weightx, double weighty) {
       addGB(component, gridx, gridy, 1, 1, NONE, weightx, weighty, CENTER, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, double weightx, double weighty, int ipadx, int ipady) {
       addGB(component, gridx, gridy, 1, 1, NONE, weightx, weighty, CENTER, new Insets(0, 0, 0, 0), ipadx, ipady);
   }
   private void addGB(Component component, int gridx, int gridy, double weightx, double weighty, int anchor) {
       addGB(component, gridx, gridy, 1, 1, NONE, weightx, weighty, anchor, new Insets(0, 0, 0, 0), 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, double weightx, double weighty, int anchor, Insets insets) {
       addGB(component, gridx, gridy, 1, 1, NONE, weightx, weighty, anchor, insets, 0, 0);
   }
   private void addGB(Component component, int gridx, int gridy, int gridwidth, int gridheight,
           int fill, double weightx, double weighty, int anchor, Insets insets,
           int ipadx, int ipady) {
       GridBagConstraints constraints = new GridBagConstraints();
       constraints.gridx = gridx;
       constraints.gridy = gridy;
       constraints.gridwidth = gridwidth;
       constraints.gridheight = gridheight;
       constraints.fill = fill;
       constraints.weightx = weightx;
       constraints.weighty = weighty;
       constraints.anchor = anchor;
       constraints.insets = insets;
       constraints.ipadx = ipadx;
       constraints.ipady = ipady;
       add(component, constraints);
   }
   public static void main(String[] args) {
       SwingUtilities.invokeLater(new Runnable() {
           @Override
           public void run() {
               JFrame frame = new JFrame("GridBagLayout Example");
               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               frame.setSize(300, 200);
               frame.setLocationRelativeTo(null);
               frame.setContentPane(new GridBagLayoutExample());
               frame.setVisible(true);
           }
       });
   }

} </code=java>

GridBagLayoutExample1.jpg

Wie man sieht wird standardmäßig alles in der Mitte ausgerichtet.

GridBagConstraints - Bedingungen für die Anordnung im Layout

Im obigen Beispiel wurde ein Objekt der Klasse GridBagConstraints benutzt. Was GridBagConstraints sind und wozu die dienen, wird im Folgenden erklärt.
GridBagConstraints sind Variablen die die Dimensionen und die Ausrichtung von GUI-Elementen in einem GridBagLayout bestimmen.

GridBagLayout ist sehr verschieden vom GridLayout, trotz des ähnlichen Namens. Anders als bei GridLayout können die Komponenten verschieden groß sein und eine Komponente kann sich über mehrere Zeilen und Spalten erstrecken. Zeilen können auch unterschiedlich hoch und Spalten unterschiedlich breit sein, gemäß der gewünschten Größe der dort untergebrachten Komponenten (preferredSize, bzw. minimumSize falls die preferredSize zu groß ist). Eine Komponente kann auch kleiner sein als ihr Anzeigebereich. Unter Anzeigebereich verstehen wir hier die Fläche der zugeordneten Zelle[n] einer Komponente.

Besondere Vorsicht ist geboten, wenn die preferredSize einer Komponente keinen festen Wert hat und sich durch Benutzereingaben verändern kann, wie zum Beispiel bei einem JTextField. Es mag dann besser sein, der preferredSize einen festen Wert zu geben, wodurch verhindert wird, dass sich das Layout ungewollt verschiebt.

Um das Layout zu planen, zeichnen wir am besten erstmal ein passendes Raster, auf das wir die Komponenten einzeichnen. Dann können wir ihre jeweiligen Constraints leichter festlegen.

gridx, gridy

Das sind int-Werte, welche die Koordinaten der oberen linken Zelle einer Komponente im Raster darstellen, wobei gridx die Spalte festlegt und gridy die Zeile. Der Defaultwert RELATIVE bedeutet, dass diese Komponente neben/unterhalb der zuvor hinzugefügten Komponente platziert wird. Um 5 ein-zellige Komponenten kreuzförmig in drei Spalten und drei Zeilen anzuordnen, können wir zum Beispiel folgende Koordinaten benutzen: <code=java> addGB(new JButton("Norden"), gridx = 2, gridy = 1); addGB(new JButton("Westen"), gridx = 1, gridy = 2); addGB(new JButton("Zentrum"), gridx = 2, gridy = 2); addGB(new JButton("Osten"), gridx = 3, gridy = 2); addGB(new JButton("Süden"), gridx = 2, gridy = 3); </code=java>

Obwohl die Koordinaten eigentlich bei 0 beginnen, haben wir der Klarheit halber in diesem Beispiel die Zeile 0 und die Spalte 0 nicht belegt. In diesem Fall schreiben wir also einfach gridx=1 für die erste Spalte und gridy=1 für die erste Zeile.

Bild 1 GridBagLayoutExample1.jpg

gridwidth, gridheight

Gibt die Anzahl der Zellen in einer Zeile / Spalte für die Komponente an. Der Standardwert ist 1. Wir verwenden REMAINDER um anzugeben, dass die Komponente von gridx / gridy bis zur letzten Zelle in der Zeile / Spalte reicht. Um im obigen Beispiel der nördlichen Komponente drei horizontale Zellen zuzuordnen, beginnend mit der ersten Spalte, können wir die folgenden Constraints verwenden: <code=java> addGB(new JButton("Norden, jetzt über drei Spalten"), gridx = 1, gridy = 1, gridwidth = 3); </code=java> Bild 2GridBagLayoutExample2.jpg

Oder statt dessen wollen wir vielleicht der westlichen Komponente drei vertikale Zellen zuordnen. In dem Fall können wir die folgenden Constraints angeben: <code=java> addGB(new JButton("<html>Westen
jetzt
über
drei Zeilen
"), gridx = 1, gridy = 1, gridwidth = 1, gridheight = 3); </code=java> Bild 3GridBagLayoutExample3.jpg

Wir können natürlich auch einer Komponente mehrere horizontale und mehrere vertikale Zellen zuordnen, wie hier der Westen mit zwei Spalten und zwei Zeilen: <code=java> addGB(new JButton("Norden"), gridx = 3, gridy = 1); addGB(new JButton("<html>Westen Westen
Westen Westen"), gridx = 1, gridy = 1, gridwidth = 2, gridheight = 2); addGB(new JButton("Zentrum"), gridx = 3, gridy = 2); addGB(new JButton("Osten Osten"), gridx = 2, gridy = 3, gridwidth = 2); addGB(new JButton("Süden"), gridx = 1, gridy = 3); </code=java>

Bild 3aBild3a.jpg

fill

Wenn der Anzeigebereich einer Komponente größer ist als die gewünschte Größe der Komponente (preferredSize / minimalSize), können wir die Komponente horizontal, vertikal oder in beide Richtungen skalieren. Die folgenden Werte sind gültig für die "fill" Eigenschaft:

   * NONE: die Komponente nicht skalieren
   * HORIZONTAL: die Komponente breit genug machen, um ihren Anzeigebereich horizontal zu füllen
   * VERTICAL: die Komponente groß genug machen, um ihren Anzeigebereich vertikal zu füllen
   * BOTH: die Komponente soll den ganzen Anzeigebereich füllen

Der Standardwert ist NONE, also keine Skalierung.

Die nördliche Komponente aus obigem Beispiel kann man mit folgenden Constraints horizontal skalieren: <code=java> addGB(new JButton("Norden"), gridx = 1, gridy = 1, gridwidth = 3, gridheight = 1, fill = HORIZONTAL); </code=java> (siehe Bild 4)

Mit der folgenden import Anweisung kann man übrigens die statischen Konstanten importieren, um nicht immer die Klasse davor schreiben zu müssen (d.h. man kann dann z.B. HORIZONTAL schreiben statt GridBagConstraints.HORIZONTAL): <code=java> import static java.awt.GridBagConstraints.*; </code=java>

weightx, weighty

Damit die Komponenten nicht im Zentrum des Panels gebündelt bleiben, sondern sich über die zur Verfügung stehende Fläche verteilen können, müssen wir dem Layout sagen, wie der zusätzliche Platz verteilt werden soll. Das geschieht mit weightx zum Verteilen des horizontalen Raums und weighty zum Verteilen des vertikalen Raums. Der zusätzliche Raum wird auf jede Spalte / Zeile im Verhältnis zum Gewicht verteilt. Der Standardwert ist 0, was bedeutet, dass die Spalte / Zeile nie zusätzlichen Raum erhält. Wenn wir der zweiten Spalte im obigen Beispiel allen zusätzlichen horizontalen Raum geben wollen, können wir das auf folgende Weise mit weightx programmieren: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 1.0, weighty = 0.0); </code=java> Bild 4GridBagLayoutExample4.jpg

Es genügt, wenn wir das Gewicht für eine einzige Komponente einer Spalte / Zeile angeben. Der Layout-Manager setzt das Gewicht der Spalte / Zeile gleich dem maximalen Gewicht der Komponenten in dieser Spalte / Zeile.

Wenn mehrzellige Komponenten benutzt werden, geht der extra Raum tendenziell in Richtung der Spalte ganz rechts und untere Reihe.

Mit weighty können wir auch zum Beispiel der zweiten Zeile allen zusätzlichen vertikalen Raum zuordnen: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 0.0, weighty = 1.0); </code=java> Bild 5GridBagLayoutExample5.jpg

Oder beides kombinieren: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 1.0, weighty = 1.0); </code=java> Bild 6GridBagLayoutExample6.jpg

Und so bekommt die zweite Spalte von dem zusätzlichen horizontalen Raum doppelt so viel wie die erste: <code=java> addGB(new JButton("Westen"), gridx = 1, gridy = 2, weightx = 1.0, weighty = 0.0); addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 2.0, weighty = 0.0); </code=java> Bild 7GridBagLayoutExample8.jpg

Man erkennt, dass die erste Spalte 20 Pixel (10 Pixel links und rechts von "Westen") zusätzlichen horizontalen Raum erhalten hat und die zweite Spalte doppelt so viel, nämlich 40 Pixel (20 Pixel links und rechts von "Zentrum").

anchor

Dieses Feld wird verwendet, wenn die Komponente kleiner ist als ihr Anzeigebereich. Damit bestimmen wir, wo die Komponente innerhalb ihrer Anzeigefläche platziert wird. Standardmäßig wird sie zentriert.

Es gibt drei Arten von möglichen Werten: orientierungsbezogene, grundlinienbezogene und absolute Werte. Orientierungsbezogene Werte beziehen sich auf die Komponentenorientierung des Containers, grundlinienbezogenen Werte beziehen sich auf die Grundlinie (Baseline, seit JDK 1.6).

Die absoluten Werte sind: CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, and NORTHWEST.

Die orientierungsbezogenen Werte sind: PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_START und LAST_LINE_END.

Die grundlinienbezogene Werte sind: BASELINE, BASELINE_LEADING, BASELINE_TRAILING, ABOVE_BASELINE, ABOVE_BASELINE_LEADING, ABOVE_BASELINE_TRAILING, BELOW_BASELINE, BELOW_BASELINE_LEADING und BELOW_BASELINE_TRAILING.

Der Standardwert ist CENTER.

Wenn wir das Beispiel von Bild 6 so umändern wollen, dass "Zentrum" oben links in seiner Zelle steht, können wir das so programmieren: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 1.0, weighty = 1.0, anchor = NORTHWEST); </code=java> Bild 8GridBagLayoutExample9.jpg

insets

Dieses Feld gibt die Außenpolsterung der Komponente an, das heißt den Mindestabstand zwischen der Komponente und den vier Kanten ihres Anzeigebereichs.

Der Standardwert ist: new Insets (0, 0, 0, 0), was bedeutet, dass die Komponente keine Außenpolsterung hat.

Wenn wir das Beispiel von Bild 8 so umändern wollen, dass oben und links von "Zentrum" ein Abstand von 10 Pixel entsteht, können wir das so programmieren: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 1.0, weighty = 1.0,

   anchor = NORTHWEST, insets = new Insets(10, 10, 0, 0));

</code=java> Bild 9GridBagLayoutExample12.jpg

ipadx, ipady

Diese Felder geben die Innenpolsterung der Komponente an, das heißt den Raum, welcher der Komponente hinzugefügt wird, wodurch diese größer wird. Dabei wird die Breite der Komponente mit ipadx gepolstert und ihre Höhe mit ipady.

Der Standardwert für beide Felder ist 0, was bedeutet, dass die Komponente keine Innenpolsterung hat.

Wenn wir das Beispiel von Bild 6 so umändern wollen, dass "Zentrum" in der Breite und in der Höhe um 20 Pixel vergrößert wird, können wir das so programmieren: <code=java> addGB(new JButton("Zentrum"), gridx = 2, gridy = 2, weightx = 1.0, weighty = 1.0, ipadx = 20, ipady = 20); </code=java> Bild 10GridBagLayoutExample11.jpg


--VuuRWerK 08:11, 11. Aug 2008 (UTC)
--L-ectron-X 11:43, 03. Jun 2010 (UTC)
--AndreUhres 16:43, 06. Dec 2010 (UTC)