Thema in Kurzform
In JavaFX können einzelne GUI-Nodes in vordefinierten Layouts angeordnet werden. Diese Layouts werden auch als Container bezeichnet und werden durch die JavaFX-Klassen im Paket javafx.scene.layout.Pane repräsentiert.
In diesem Tutorial stellen wir dir einige der wichtigsten Layout-Klassen in JavaFX vor und zeigen dir, wie einfach sie zu benutzen sind.
Ein sehr einfaches Layout ist die HBox. Wenn wir das HBox-Layout verwenden, werden alle Kind-Elemente in einer horizontalen Linie angeordnet:
HBox hbox = new HBox();
hbox.setPadding(new Insets(20,20,20,20));
hbox.setSpacing(20);
TextField tf = new TextField();
Button b1 = new Button("Button 1");
Button b2 = new Button("Button 2");
hbox.getChildren().addAll(tf,b1,b2);
primaryStage.setScene(new Scene(hbox, 400, 200));
primaryStage.setTitle("HBox Beispiel");
primaryStage.show();
Wie du siehst, ist das ganze ziemlich easy:
Wir instanziieren ein neues HBox-Objekt und passen danach noch etwas das Layout mit den Methoden setPadding() und setSpacing() an. Anschließend erzeugen wir drei Test-Nodes und fügen diese als Child-Elemente mit der Methode hbox.getChildren().addAll(tf,b1,b2); dem HBox-Container hinzu.
Die VBox ist vom Grundprinzip der HBox sehr ähnlich. Der einzige Unterschied ist, dass die Kind-Elemente bei der VBox in einer vertikeln Reihe angeordnet werden:
VBox vbox = new VBox();
vbox.setPadding(new Insets(20,20,20,20));
vbox.setSpacing(20);
TextField tf = new TextField();
Button b1 = new Button("Button 1");
Button b2 = new Button("Button 2");
vbox.getChildren().addAll(tf,b1,b2);
primaryStage.setScene(new Scene(vbox, 400, 200));
primaryStage.setTitle("VBox Beispiel");
primaryStage.show();
Ein FlowPane layoutet seine Kind-Elemente der Reihe nach (standartmäßig) von links nach rechts nacheinander an. Wenn der Rand der Scene erreicht ist, bricht der FlowPane die Elemente in die nächste Zeile um.
Schau dir das Beispiel hier an: Wir erzeugen mithilfe einer Schleife 101 Labels mit den Zahlen von 0 bis 100 und fügen diese nacheinander dem FlowPane mit fp.getChildren().add(l); hinzu:
FlowPane fp = new FlowPane();
for(int i = 0; i < 101; i++){
Label l = new Label(" " + i);
fp.getChildren().add(l);
}
primaryStage.setScene(new Scene(fp, 400, 200));
primaryStage.setTitle("FlowPane Beispiel");
primaryStage.show();
Wollen wir den Fluss der Nodes nicht horizontal, sondern "spaltenmäßig" vertikal (=von oben nach unten) haben, setzen wir die Orientation einfach auf VERTICAL:
fp.setOrientation(Orientation.VERTICAL);
Das BorderPane Layout ist sehr beliebt unter JavaFX-Programmierern, da es sehr einfach zu handeln ist und gleichzeitig schon viele Layout-Anforderungen erfüllt. Es gutes Basis-Layout also. Bei der Verwendung des BorderPane Layouts werden die einzelnen Nodes in den Bereichen Top, Left, Right, Center und Bottom angeordnet:
Mit den Methoden setTop(), setCenter(), setLeft(), setRight() und setBottom() lassen sich die einzelnen Nodes den Bereichen des BorderPane Layouts zuweisen.
BorderPane bp = new BorderPane();
bp.setTop(new TextField("Top"));
bp.setBottom(new TextField("Bottom"));
bp.setLeft(new TextField("Left"));
bp.setRight(new TextField("Right"));
bp.setCenter(new TextField("Center"));
primaryStage.setScene(new Scene(bp, 400, 200));
primaryStage.setTitle("BorderPane Beispiel");
primaryStage.show();
Besonders nützlich ist die BorderPane für die Layout-Verschachtelung, d.h. wir verwenden es als Container für weiterer Layouts nutzen. So können wir zum Beispiel ein HBox-Layout mit mehreren Buttons in einen der fünf BorderPane-Bereiche einsetzen:
BorderPane bp = new BorderPane();
bp.setBottom(new TextField("Bottom"));
bp.setLeft(new TextField("Left"));
bp.setRight(new TextField("Right"));
bp.setCenter(new TextField("Center"));
// Hbox mit Buttons erstellen
HBox hbox = new HBox();
Button b1 = new Button("01");
Button b2 = new Button("02");
Button b3 = new Button("03");
Button b4 = new Button("04");
hbox.setAlignment(Pos.CENTER);
hbox.getChildren().addAll(b1, b2, b3, b4);
// HBox in BorderPane einsetzen
bp.setBottom(hbox);
primaryStage.setScene(new Scene(bp, 400, 200));
primaryStage.setTitle("BorderPane Beispiel");
primaryStage.show();
Du siehst: Mit der BorderPane kann man so einiges anstellen 🤩
Das StackPane Layout ordnet die Child-Nodes in einem back-to-front stack an. Das bedeutet, dass die Elemente im StackPane gestapelt werden. Mit anderen Worten: Das erste hinzugefügte Elemente liegt "ganz unten" und das zuletzt hinzugefügte ist ganz "oben" angeordnet.
StackPane sp = new StackPane();
Label boden = new Label();
boden.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("boden.png"))));
Label link = new Label();
link.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("link.png"))));
Button button = new Button();
button.setPrefSize(150, 50);
sp.getChildren().addAll(boden, button, link);
primaryStage.setScene(new Scene(sp, 400, 200));
primaryStage.setTitle("StackPane Beispiel");
primaryStage.show();
In diesem Beispiel erstellen wir zunächst nacheinander drei Node-Objekte: Ein Label mit Grafik (boden.png), einen Button und noch ein Label mit einer Grafik (link.png).
Anschließend werden die drei Nodes mit der Methode addAll() der StackPane hinzugefügt. Die Reihenfolge des Hinzufügens ist für die Darstellung entscheidend, wie du hier siehst:
Konkret sieht das so aus, dass das Label mit der Boden-Grafik ganz unten liegt, es folgt der Button. Ganz oben ist dann die Spielfigur Link gesetzt.
Standardmäßig werden die Nodes zentriert, also in der Mitte des StackPanes, angeordnet. Hier kann man aber mit der Methode setAlignment() die Ausrichtung für jedes Node einzeln ändern. Zum Beispiel:
sp.setAlignment(link, Pos.TOP_CENTER); // Ausrichtung Figur oben zentriert
sp.setAlignment(button, Pos.BOTTOM_RIGHT); // Ausrichtung Button unten rechts
Für eine sehr flexible und freie Anordnung der Child-Nodes (in Bezug auf den Fensterrand) eignet sich das AnchorPane Layout ausgezeichnet:
AnchorPane ap = new AnchorPane();
// Nodes erstellen
Button button = new Button("A Link to the Past");
button.setPrefSize(150, 50);
Label link = new Label();
link.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("link.png"))));
// Nodes dem AnchorPane hinzufügen
ap.getChildren().addAll(button, link);
// Nodes Position frei wählen
button.setLayoutX(75);
button.setLayoutY(50);
link.setLayoutX(125);
link.setLayoutY(125);
primaryStage.setScene(new Scene(ap, 300, 200));
primaryStage.setTitle("AnchorPane Beispiel");
primaryStage.show();
Mit den Methoden setLayoutX() und setLayoutY() können wir die Pixelpositionen X und Y im Abstand zum linken bzw. oberen Rand des AnchorPane angeben. Damit ist es möglich, unsere Nodes frei nach belieben zu positionieren.
Sehr cool ist das vor allem für das Game Development in Java - ja, das geht wirklich 👾
Java Basics
[Java einrichten] [Variablen] [Primitive Datentypen] [Operatoren] [if else] [switch-case] [Arrays] [Schleifen]
Objektorientierung
[Einstieg] [Variablen ] [Konstruktor] [Methoden] [Rekursion] [Statische Member] [Initializer] [Pass-by-value] [Objektsammlungen] [Objektinteraktion] [Objekte löschen]
Klassenbibliothek
[Allgemeines] [String ] [Math] [Wrapper] [Scanner] [java.util.Arrays] [Date-Time-API]
Vererbung
[Einstieg Vererbung] [Konstruktoren bei Vererbung ] [Der protected Zugriffsmodifikator] [Abstrakte Klassen und Methoden] [Polymorphie in Java] [Typumwandlung] [Die Klasse Object] [Die toString()-Methode] [Objekte vergleichen] [Was ist ein Interface?]