I have this very simple form and I set the min width and height of all UI controls to be USE_PREF_SIZE, so, they cannot get too small:
The code looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<AnchorPane minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
<children>
<GridPane hgap="10.0" layoutX="64.0" layoutY="122.0" vgap="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints halignment="RIGHT" hgrow="NEVER" />
<ColumnConstraints hgrow="SOMETIMES" />
</columnConstraints>
<rowConstraints>
<RowConstraints vgrow="NEVER" />
<RowConstraints vgrow="NEVER" />
<RowConstraints vgrow="NEVER" />
<RowConstraints valignment="TOP" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label minHeight="-Infinity" minWidth="-Infinity" text="Log in" GridPane.columnSpan="2147483647" GridPane.halignment="CENTER" />
<Label minHeight="-Infinity" minWidth="-Infinity" text="Email address:" GridPane.rowIndex="1" />
<Label minHeight="-Infinity" minWidth="-Infinity" text="Password:" GridPane.rowIndex="2" />
<Button minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" text="Log in" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="3" />
<PasswordField minHeight="-Infinity" minWidth="-Infinity" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<TextField minHeight="-Infinity" minWidth="-Infinity" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</GridPane>
</children>
</AnchorPane>
My problem is that the window can still get too small:
How do I prevent that from happening?
I could of course set a fixed min width and height, that's trivial:
stage.setMinWidth(280);
stage.setMinHeight(180);
but that requires remembering to update it every time the UI changes and it wouldn't be sufficient in other languages that have longer strings, such as Spanish:
Since it seems this cannot be achieved with FXML, I'm trying with code. The basic code I'm starting with is the usual FXML loading method:
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/simple_form.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
The FXML loaded object, root, has a prefWidth and prefHeight property that look promising. I added this debugging prints:
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/simple_form.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
System.out.println("Preferred width before showing: " + root.prefWidth(-1));
System.out.println("Preferred height before showing: " + root.prefHeight(-1));
stage.show();
System.out.println("Preferred width after showing: " + root.prefWidth(-1));
System.out.println("Preferred height after showing: " + root.prefHeight(-1));
System.out.println("Actual width: " + scene.getWidth());
System.out.println("Actual height: " + scene.getHeight());
}
and the result is:
Preferred width before showing: 30.0
Preferred height before showing: 50.0
Preferred width after showing: 255.0
Preferred height after showing: 142.0
Actual width: 255.0
Actual height: 142.0
Since the initial size is the preferred size, the one I want as a minimum for this UI, a sensible person would have expected to have the answer (you just need to show()
the stage first):
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/simple_form.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
stage.setMinWidth(root.prefWidth(-1));
stage.setMinHeight(root.prefHeight(-1));
}
But the result of this code is that I can still make the Window smaller, but only a little bit:
I'm utterly confused by that result. I tried removing the paddings and gaps from the fxml, but the odd behavior remained.