Wie kann ich Elemente in meinem JavaFX Programm an die Fenstergröße anpassen?
Ich möchte dass, egal wie groß mein Fenster ist meine Labels immer zentriert sind und der Abstand links und rechts gleich ist. Ich benutze eine BorderPane und im Center eine AnchorPane? Sollte man etwas anderes benutzen? Es soll die ganze Zeit "geupdated/geresized" werden dass sich meine Elemente immer an die Fenstergröße anpassen.
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="578.0" prefWidth="460.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="net.htlgkr.pos.lugerspreitzer.projekt_jfx_muehle.MenuController">
<center>
<AnchorPane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Label layoutX="218.0" layoutY="44.0" text="Start" />
<Label layoutX="218.0" layoutY="289.0" text="Chat" />
<Label layoutX="216.0" layoutY="219.0" text="Rules" />
<Label layoutX="215.0" layoutY="134.0" text="Game" />
<Label layoutX="190.0" layoutY="391.0" text="something else" />
</children>
</AnchorPane>
</center>
</BorderPane>
1 Antwort
Die Elemente deines Fensters werden sich nicht responsive verhalten, gerade da du sie mit einem AnchorPane (bzw. fixen Größen und Koordinaten) anordnest.
Für ein adaptives/responsive Design wäre Folgendes zu beachten:
1) Verwende zur Anordnung Layout Panes wie BorderPane, GridPane, FlowPane, HBox, TilePane, VBox
2) Verzichte auf fixe Größen. Setze stattdessen eher nur Größenbereiche (z.B. Mindest-/Maximalbreite). Die präferierte Größe sollte sich an dem Inhalt ausrichten (Region.USE_COMPUTED_SIZE).
Du kannst über Constraints (siehe bspw. ColumnConstraints des GridPane) auch prozentuale Werte vorgeben oder im FXML die Werte entsprechend berechnen.
Beispiel:
<VBox fx:id="root" prefHeight="${screen.visualBounds.height}" prefWidth="${screen.visualBounds.width}">
<fx:define>
<Screen fx:factory="getPrimary" fx:id="screen" />
</fx:define>
<Label prefWidth="${root.width * 0.5}" />
</VBox>
Über die fx:factory wird die primäre Stage bezogen. Somit ist es möglich, die aktuelle Fenstergröße (visualBounds) zu ermitteln und auf dessen Grundlage die gewünschten Größen zu berechnen.
3) Was man aber auch berücksichtigen sollte: Es ist nicht unbedingt praktikabel, Elemente bei Skalierung der Fenstergröße automatisch größer/kleiner werden zu lassen. Wie bei responsive Webseiten sollte man stattdessen schauen, wie die Elemente je nach verfügbaren Platz am besten angeordnet werden.
Insofern könnte man sich auch ein eigenes Grid Layout bauen, welches bei verschiedenen Breakpoints Umbrüche erzeugt. In diesem Artikel wird die Implementation eines solchen Layout Managers gezeigt.