0

I'm creating a stage that I've made in scenebuilder and I want some of the sizes in there to be dependent on the size of the monitor. However, in scenebuilder, when setting pref width/height, I can only write a number or "USE_COMPUTED_SIZE". I know that I can get the dimensions of the screen by using the following code;

Rectangle2D screenBounds = Screen.getPrimary().getBounds();

    @FXML
    double windowHeight = screenBounds.getHeight()/2;
    @FXML
    double windowWidth = screenBounds.getHeight()/2;

is there a way to use these variables "windowHeight" and "windowWidth" in the FXML file. Like:

<AnchorPane prefHeight="windowHeight" prefWidth="windowWidth" stylesheets="@defaultStyle.css" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Menu">

(The variables "windowHeight" and "windowWidth" are declared in Menu.java)

Another preferred way to be able to do it would be if I could directly set the width and height to a variable within scenebuilder.

Perhaps, even better would be if I could set all values within scenebuilder to be by preferred ratio rather that size, so that later on, when resizing the stage, everything would change with it.

I have tried to later set the width and height of the stage when loading it but it didn't really work.

  • 4
    You can [_define_](https://openjfx.io/javadoc/19/javafx.fxml/javafx/fxml/doc-files/introduction_to_fxml.html#define_elements) arbitrary elements, for [example](https://stackoverflow.com/a/74480486/230513), but I would advocate using the computed size in a responsive layout. – trashgod Jan 08 '23 at 16:57
  • 4
    *”Perhaps, even better would be if I could set all values within scenebuilder to be by preferred ratio rather that size, so that later on, when resizing the stage, everything would change with it.”* This is what you should do. Just choose appropriate layout panes that implement this behavior; it is exactly what they are for. `AnchorPane`, which does not really implement a responsive layout, is rarely the correct choice. – James_D Jan 08 '23 at 17:17
  • 3
    your first code snippet would be plain wrong: fields annotated with fxml are supposed to be injected by the loader, they _must not_ be initialized - it's a one-way road. As already suggested in the other comments: learn all about layouts, choose an appropriate one. when stuck come back with a [mcve] demonstrating the problem – kleopatra Jan 09 '23 at 09:16
  • Another [example of `fx:define`](https://stackoverflow.com/questions/23705654/bind-font-size-in-javafx). See the usage of the `Measurement` class in my answer. Though, please heed the recommendations in other comments. I wouldn’t use the define mechanism like this unless I really needed to as it would complicate things for me. – jewelsea Jan 09 '23 at 09:49
  • This looks like a case where you are attempting to take the wrong approach to accomplish a task. My guess is that you should do this while loading an FXML. If this is the loading of the first FXML, it should be done in the `Main`. `Rectangle2D screenBounds = Screen.getPrimary().getBounds(); Parent root = FXMLLoader.load(getClass().getResource("LoginScreen.fxml")); Scene scene = new Scene(root, screenBounds.getWidth()/2, screenBounds.getHeight()/2);` – SedJ601 Jan 10 '23 at 05:25

1 Answers1

-2

Maybe you can initialize the bounds of AnchorPane in the controller class instead of using variables ,since it is not allowed to be.
Perhaps you should implement the Controller class with Initializable class to over ride the initialize method.
As names suggests , you can initialize the component of the fxml file using that method.
And of course you can inside that method set the bounds by root.setPrefHeight(customVariable);.

Full code:


import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;

public class Controller implements Initializable {

@fxml
public AnchorPane root;
public int height = 180;
public int width = 200;

@Override
public void initialize(URL location, ResourceBundle resources) {
    root.setPrefHeight(height);
    root.setPrefWidth(width);
    }
}