JavaFX AnchorPane resizen, aber wie?

Tom299

Bekanntes Mitglied
Hi,

ich hab meine Screens alle mit AnchorPane's gebaut, weil ich da sehr einfach und schnell positionieren kann. Bis gestern hatte ich aber noch kein resize versucht.
Leider tut sich beim resize rein gar nix, der Screen wandert einfach in der urspünglichen Größe in die linke obere Ecke anstatt daß die AnchorPane maximiert wird.
Ich hab schon bei stackoverflow nach Lösungen gesucht, aber gebracht hat es bei mir nichts.

Hier mal mein FXML, vielleicht sieht jemand, was fehlt oder falsch eingestellt ist (Ist der Login-Screen, der hat die wenigsten Komponenten):
Code:
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane id="ctrlLogin" fx:id="ctrlLogin" maxHeight="-1.0" maxWidth="-1.0" minHeight="60.0" minWidth="80.0" prefHeight="600.0" prefWidth="800.0" stylesheets="@styles/login.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.temeka.prokal.berichte.controller.LoginController">
   <children>
      <GridPane hgap="5.0" layoutX="232.0" layoutY="300.0" vgap="7.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="110.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="110.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="3.0" prefHeight="3.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label GridPane.columnSpan="3" GridPane.halignment="LEFT">
               <font>
                  <Font name="Arial Bold" size="18.0" />
               </font>
            </Label>
            <Label text="Benutzername" GridPane.rowIndex="1">
               <font>
                  <Font name="Arial" size="14.0" />
               </font>
            </Label>
			<ComboBox fx:id="cboBenutzer" editable="true" prefHeight="30.0" prefWidth="205.0" promptText="Bitte wählen ..." GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1" />            
            <Label text="Kennwort" GridPane.rowIndex="2">
               <font>
                  <Font name="Arial" size="14.0" />
               </font>
            </Label>
            <PasswordField fx:id="pwdKennwort" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="2">
               <font>
                  <Font name="Arial" size="14.0" />
               </font>
               <GridPane.margin>
                  <Insets right="20.0" />
               </GridPane.margin>
            </PasswordField>
            <Button fx:id="btnCancel" cancelButton="true" mnemonicParsing="false" onAction="#doCancel" prefWidth="90.0" text="Abbrech" GridPane.columnIndex="1" GridPane.rowIndex="4">
               <font>
                  <Font name="Arial" size="14.0" />
               </font>
            </Button>
            <Button fx:id="btnLogin" defaultButton="true" mnemonicParsing="false" onAction="#doLogin" prefWidth="90.0" text="Login" GridPane.columnIndex="2" GridPane.rowIndex="4">
               <font>
                  <Font name="Arial" size="14.0" />
               </font>
            </Button>
         </children>
      </GridPane>
      <ImageView fitHeight="240.0" fitWidth="310.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="391.0" AnchorPane.leftAnchor="232.0" AnchorPane.rightAnchor="258.0" AnchorPane.topAnchor="54.0">
         <image>
            <Image url="@../images/javafx.png" />
         </image>
      </ImageView>
   </children>
</AnchorPane>

PrefWidth und PrefHeight sind auf 800*600 eingestellt. Das hab ich auch schon testweise geändert, hat aber auch keine Auswirkungen aufs resize gehabt, nur daß der Screen dann unbrauchbar aussieht.

Ich dachte eigentlich, die AnchorPane ist schlauer als das Null-Layout bei Swing. Hoffe ich habe mich da nicht getäuscht und muß alle Screens mit einem anderen Layout umbauen?

Hier 3 Screenshots mit normal (800*600) und dann etwas größer und etwas kleiner gezogen:
Test_Normal.png
Test_Resize.png
Test_Resize2.png

Gruß Tom
 
Ich hab zwar rausgefunden, wie ich im Code manuell resizen kann, aber das ist ja mühseelig und kann nicht Sinn der Sache sein:

Beispiel-Resize:
Code:
		ctrlLogin.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
			public void changed(javafx.beans.value.ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
				//System.out.println(newValue.getWidth() + "x" + newValue.getHeight());
				AnchorPane.setTopAnchor(gridPane, newValue.getHeight()*300/600);
				AnchorPane.setBottomAnchor(gridPane, newValue.getHeight()*150/600);
				AnchorPane.setLeftAnchor(gridPane, newValue.getWidth()*232/800);
				AnchorPane.setRightAnchor(gridPane, newValue.getWidth()*238/800);
				
				AnchorPane.setTopAnchor(ivLogo, newValue.getHeight()*54/600);
				AnchorPane.setBottomAnchor(ivLogo, newValue.getHeight()*313.5/600);
				AnchorPane.setLeftAnchor(ivLogo, newValue.getWidth()*232/800);
				AnchorPane.setRightAnchor(ivLogo, newValue.getWidth()*258/800);
			};
		});
 
Ich würde dir gern helfen, aber ich hab - um ehrlich zu sein - noch nie AnchorPanes verwendet, sondern setze immer auf VBox, HBox, BorderPane, SplitPane, ScrollPane, StackPane, FlowPane und GridPane.
Ich denke, AnchorPane funktioniert gut innerhalb eines anderen Layouts, wenn du es eben gut an anderen Nodes verankern kannst. Bzw. denke ich nicht, dass es praktisch ist, mit absoluten Zahlenwerten zu arbeiten.
Ich würde in deinem Bsp. Wohl ein GridPane als root wählen und darin evtl. mit Column-/RowSpan arbeiten...
 
Also ich hatte in meiner 1. View sogar das GridPan verwendet, aber ich finde es viel umständlicher beim Anordnen als mit dem AnchorPane.

Mir war aber aufgefallen, daß mein "ScreenManager" scheinbar daran Schuld war, daß gar keine View resized wurde. Hab mir einen anderen geschrieben und damit funzt zumindest mal das resize generell.

AnchorPane hab ich jetzt auch richtig verstanden bzw. beim testen rausgefunden. Ich dachte, ich hätte in den JavaDocs gelesen, daß die AnchorPane die Abstände relativ zum Ausgangslayout hoch- oder runterrechnet. Also z.B. bei TopAnchor = 50.0 dachte ich, daß beim resize die 50.0 auf z.B. 100.0 hochgerechnet wird, wenn ich die Höhe verdoppele. Doch genau das passiert nicht, er behält immer genau die 50.0 bei. Deswegen konnte ich z.B. den Login-Screen nicht automatisch zentrieren lassen, sondern da ich AnchorLeft und Top angegeben habe, hält die AnchorPane diese Werte bei.

Wo es aber gut funktoniert ist z.B. bei einer TableView oder einem Button-Panel im oberen oder unteren Bereich. Da gibt man die Top und Bottom Anchors an bzw. beim ButtonPanel nur Bottom und Right z.B. und dann sieht das auch anständig aus. Nur wenn man viele Eingabefelder und Labels hat, bekommt man Probleme.

Also so wie es aussieht muß ich ein paar Views umbauen, aber zum Glück nicht alle 🙂
 

Neue Themen


Zurück
Oben