javajavafxjavafx-css

Why does JavaFX Node have wrong sizes in initialize method after css is applied?


I have a VBox that have several AnchorPane. I decided to add css style to these AnchorPane: -fx-border-width. But the VBox is inside another "main" AnchorPane, and main AnchorPane is inside the ScrollPane. If I'm adding css to elements, not all the elements in the ScrollPane will be displayed. For testing, I made border-width 0 0 10 0. I have 20 elements, so the total size of the VBox after applying the style to each element of the VBox should increase by 200. In the controller's intiailize() method, after calling the layout() and applyCss(), getHeight( ) for the VBox returns 1200 (and I know that is the height of VBox if I wouldn't add css). Then for the main anchorPane I'm setting the height setPrefHeight(vbox.getHeight()). But after my application finally runs, I see that the VBox size is 1400 as expected. But the size of the AnchorPane still 1200, and therefore if I will scroll to the end, some elements inside the ScrollPane will not be visible. How can I fix it?

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    for (int i = 0; i < 20; i++) {
        addElementsToVBox();
    }

    vbox.applyCss();
    vbox.layout();

    mainAnchorPane.applyCss();
    mainAnchorPane.layout();

    System.out.println(vbox.getHeight()); //in my case will be 1200, 
    //but after the application will complete the loading, vbox.getHeight() will return 1400
    //if I would invoke it from button's onAction() for example

    mainAnchorPane.setPrefHeight(vbox.getHeight());
}

private void addElementsToVBox() {
    Label label = new Label();
    label.setText("Test");
    
    AnchorPane anchorPane = new AnchorPane();
    anchorPane.getChildren().add(label);
    anchorPane.setPadding( new Insets(2, 0, 2, 0) );
    anchorPane.setStyle("-fx-border-width: 0 0 10 0; -fx-border-color: black");
    anchorPane.applyCss();
    anchorPane.layout();

    vbox.getChildren().add(anchorPane);
}

Solution

  • In my case, I was using mainAnchorPane.setPrefHeight(vbox.getHeight()) because after experiments I noticed that without that method mainAnchorPane wouldn't change the height. That is because I set exact pref height value for AnchorPane in SceneBuilder. But after setting USE_COMPUTED_SIZE, my AnchorPane will have the size that I actually want. So all I need is:

    set computed size for all fields