Beispiel: GridBayLayout-Grundlagen
Inhalt:
Allgemein
Basics
Komponenten vergrößern und über mehrere Zellen strecken
Platz zwischen mehreren Komponenten aufteilen
Hier werden ein paar Grundlagen des GridBayLayouts erklärt.
Hier gibt es das Projekt zum Download (dies ist exportiert über "General" -> "Archive file"): GridBayLayout.zip
Re-Import:
- Ein Java-Projekt namens "GridBayLayout" im Workspace anlegen
- Importieren als "General" -> "Archive File", als Zielverzeichnis das eben angelegte Java-Projekt angeben.
- Wenn hier eine Warnmeldung "Overwrite .project in folder 'GridBayLayout'" kommt, dann sind wir auf der Gewinnerseite, sonst stimmt vermutlich die Verzeichnisstruktur nicht.
- Fertisch.
Allgemein
Das GridBayLayout ist der mächtigstes und dadurch leider auch komplizierteste Layout-Manager. Er betrachtet ein Fenster
(bzw. ein einzelnes JPanel darauf, man kann GridBayLayouts pro Container-Komponente definieren) als Tabelle, wobei in jeder Zelle
eine GUI-Komponente steckt. Für diese Zellen kann man angeben, wie verfügbarer freier Platz im Dialog auf sie verteilt werden soll. Komponenten können sich
über mehrere Tabellenzellen erstrecken. Im folgenden ein paar einfache Beispiel (die Beispielanwendung enthält drei Buttons, die einige Layout-Varianten demonstrieren).
Basics
Ein GridBayLayout wird so definiert (am Beispiel meines Hauptfensters, das von javax.swing.JFrame
abgeleitet ist):
GridBagLayout gridBayLayout = new GridBagLayout();
this.setLayout(gridBayLayout);
Jetzt werden dem Layout einzelne Komponenten zugefügt (in meinem Beispiel das Hauptfenster).
Für jede Komponente müssen java.awt.GridBagConstraints
definiert werden, die
die Zelle innerhalb der Tabelle beschreiben (erster und zweiter Konstruktorparameter). Im folgenden wird nicht weiter auf die weiteren Parameter eingegangen.
JButton buttonTextAreaMax = new JButton ("TextArea maximiert");
gridBayLayout.setConstraints(buttonTextAreaMax, new GridBagConstraints (0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(buttonTextAreaMax);
JButton buttonTextAreaButtons = new JButton ("TextArea mit zwei Buttons");
gridBayLayout.setConstraints(buttonTextAreaButtons, new GridBagConstraints (0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(buttonTextAreaButtons);
JButton button3x2TextAreas = new JButton ("3*2 TextAreas");
gridBayLayout.setConstraints(button3x2TextAreas, new GridBagConstraints (0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(button3x2TextAreas);
Parameter drei und vier geben an, wie sich die Tabellenzelle verhalten soll, wenn der verfügbare Platz in der Parentkomponente größer ist als die Minimumgröße
der Komponente. Man definiert hier einen Faktor, der erstaunlicherweise nicht unbedingt ein Wert zwischen 0.0 und 1.0 sein muss. Für die Ermittlung des effektiven
Größenfaktors einer Zelle summiert das GridBayLayout nämlich alle Faktoren einer Spalte bzw. Zeile, und setzt den x-/y-Faktor der aktuellen Zelle ins Verhältnis hierzu.
Wenn im obigen Beispiel also alle drei Buttons einen y-Faktor von 3 haben, dann hat jeder der Buttons einen effektiven Faktor von "1/3". Das bedeutet, dass
die Zellen der Buttons gleichwertig vergrößert werden. Da der Fill-Modus der Buttons auf GridBagConstraints.NONE
steht, ändert sich an der Button-Größe
nichts, hier hat das GridBayLayout also nichts zu verteilen.
Das Ergebnis sieht so aus:
Button 1 |
Button 2 |
Button 3 |
Komponenten vergrößern und über mehrere Zellen strecken
Beispiel 2 (in meinem Beispiel über den Button "TextArea maximiert" erreichbar) zeigt ein TextArea, unter dem zwei Buttons liegen. Das TextArea soll sich vergrößern,
die Buttons bleiben gleich.
Das Fenster sieht so aus:
TextArea |
Button 1 |
Button 2 |
Der Code sieht so aus:
JScrollPane scrollPane = new JScrollPane();
gridBayLayout.setConstraints(scrollPane, new GridBagConstraints (0, 0, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane);
JTextArea textArea = new JTextArea();
scrollPane.getViewport().add(textArea);
JButton button1 = new JButton ("Button 1");
gridBayLayout.setConstraints(button1, new GridBagConstraints (0, 1, 1, 1, 0.5, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(button1);
JButton button2 = new JButton ("Button 2");
gridBayLayout.setConstraints(button2, new GridBagConstraints (1, 1, 1, 1, 0.5, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(button2);
Zuerst die Angaben für das JScrollPane
:
- Parameter "gridwidth" und "gridheight" sind 2 bzw. 1. Dies bedeutet: diese Komponente ersteckt sich in x-Richtung über 2 Zellen, in y-Richtung über 3 Zellen.
- Parameter "weightx" und "weighty" stehen auf "1.0". Da es in x-Richtung keine weitere Komponente gibt und in y-Richtung nur die Buttons liegen, die selbst ein "weighty" von 0 definieren,
erhält das
JScrollPane
also allen verfügbaren Platz.
- Damit es den auch nutzt, muss der Parameter "fill" auf
GridBagConstraints.BOTH
(in beide Richtungen stecken)
Für die beiden Buttons sind die Angaben identisch.
- Sie liegen in Zelle "0/1" (Spalte 0, Zeile 1) bzw. "1/1" (Spalte 1, Zeile 1).
- Parameter "weightx" steht jeweils auf "0.5" (in der Summe 1, die 0.5 wird ins Verhältnis dazu gesetzt). Dadurch teilen sich die beiden Buttons den verfügbaren Platz in x-Richtung.
Alternativ hätte man hier auch bei beiden "1" oder "5" nehmen können, Hauptsache die Summe ist gleich. In diesem Fall hätte man aber darauf achten müssen, dass das ScrollPane
den gleichen Gesamtfaktor definiert (also 2 oder 10).
"weighty" steht auf "0.0", das heißt die Buttons machen dem JScrollPane
keinen Platz streitig und begnügen sich mit dem minimal erforderlichen Platz.
Platz zwischen mehreren Komponenten aufteilen
Beispiel 3 (in meinem Beispiel über den Button "3*2 TextAreas" erreichbar) zeigt drei TextAreas in drei Zeilen und zwei Spalten.
Die TextAreas teilen den verfügbaren Platz ein wenig unfair unter sich auf:
TextArea 1/2 und 5/6 bekommen jeweils ein Viertel der verfügbaren Höhe, TextArea 3/4 bekommen die Hälfte der verfügbaren Höhe
TextArea 1/3/5 bekommen jeweils ein Drittel der verfügbaren Breite, TextArea 2/4/6 bekommen nur ein Drittel der verfügbaren Breite
Das Fenster sieht so aus (diesmal mit Bild statt schnöder Tabelle):
Der Code sieht so aus:
JScrollPane scrollPane1 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane1, new GridBagConstraints (0, 0, 1, 1, 2, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane1);
JTextArea textArea1 = new JTextArea();
scrollPane1.getViewport().add(textArea1);
JScrollPane scrollPane2 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane2, new GridBagConstraints (1, 0, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane2);
JTextArea textArea2 = new JTextArea();
scrollPane2.getViewport().add(textArea2);
JScrollPane scrollPane3 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane3, new GridBagConstraints (0, 1, 1, 1, 2, 2, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane3);
JTextArea textArea3 = new JTextArea();
scrollPane3.getViewport().add(textArea3);
JScrollPane scrollPane4 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane4, new GridBagConstraints (1, 1, 1, 1, 1, 2, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane4);
JTextArea textArea4 = new JTextArea();
scrollPane4.getViewport().add(textArea4);
JScrollPane scrollPane5 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane5, new GridBagConstraints (0, 2, 1, 1, 2, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane5);
JTextArea textArea5 = new JTextArea();
scrollPane5.getViewport().add(textArea5);
JScrollPane scrollPane6 = new JScrollPane();
gridBayLayout.setConstraints(scrollPane6, new GridBagConstraints (1, 2, 1, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0 ));
this.add(scrollPane6);
JTextArea textArea6 = new JTextArea();
scrollPane6.getViewport().add(textArea6);
Die ScrollPanes kommen in die Zellen 0/0, 1/0, 0/1, 1/1, 0/2 und 1/2.
In x-Richtung gibt es zwei Textfelder, d.h. Felder der zweiten Spalten bekommen zwei Drittel des verfügbaren Platzes (im Beispiel durch eine "weightx" von 2.0 ausgedrückt).
Felder der zweiten Spalten bekommen ein Drittel des Platzes ("weightx" = 1.0)
In y-Richtung gibt es drei Textfelder, Felder in Zeile 1 und 3 bekommen ein Viertel des verfügbaren Platzes (im Beispiel durch eine "weighty" von 1.0 ausgedrückt).
Felder in Zeile 2 bekommen die Hälfte, also eine "weighty" von 2.0.
Stand 26.03.2008
Historie:
26.03.2008: Erstellt