4

So I'm not sure how to calculate the height of the node during the .setOnAction event I have tried .requestLayout()/.applyCss() not sure what else to try I am trying to find the height of the vBox after adding a node but it is only printing the height of the node before the new one was added

public class Main extends Application {

    @Override
    public void start(Stage stage) {
        VBox vBoxContainer = new VBox();
        vBoxContainer.setAlignment(Pos.CENTER);
        vBoxContainer.setPrefSize(200,200);

        VBox vBox = new VBox();
        vBox.setAlignment(Pos.CENTER);
        for (int i = 0; i < 5; i++)
            vBox.getChildren().add(new Label("newLabel"));
        vBoxContainer.getChildren().add(vBox);

        Button button = new Button("Add Label");
        button.setOnAction(event -> {
            System.out.println("Height Before new Label:"+vBox.getHeight());
            vBox.getChildren().add(new Label("newLabel"));
            //here is where I was adding code to produce expected result
            System.out.println("Height After new Label:"+vBox.getHeight());
        });

        Button checkButton = new Button("Print VBox Height");
        checkButton.setOnAction(event -> System.out.println("VBox Height:"+vBox.getHeight()));

        vBoxContainer.getChildren().addAll(button, checkButton);

        stage.setScene(new Scene(vBoxContainer));
        stage.show();
    }
}

Run the example and Click the button that adds a Label to the vBox and it outputs

Actual Result:

Height Before new Label:85.0
Height After new Label:85.0

Expected Result:

Height Before new Label:85.0
Height After new Label:102.0    

But if you then click the Print VBox Height Button it will show the correct height of:

VBox Height:102.0
Ghost
  • 57
  • 8
  • Trying adding a listener to the VBox's height property and updated your height from there. – SedJ601 Oct 25 '19 at 15:50
  • So in my actual program I need to run more code based off of the new height would I use the listener to update a variable and use that variable in the rest of the setOnAction? – Ghost Oct 25 '19 at 15:52
  • Sounds like you just need an `if-statement` in the listener. – SedJ601 Oct 25 '19 at 15:56
  • Yea, set a variable with greater scope in the listener if you need it to be current when you press some other button. – SedJ601 Oct 25 '19 at 16:00

2 Answers2

4

You can try adding a listener to the VBox's height property.

VBox vBoxContainer = new VBox();
vBoxContainer.setAlignment(Pos.CENTER);
vBoxContainer.setPrefSize(200, 200);

VBox vBox = new VBox();
vBox.setAlignment(Pos.CENTER);
vBoxContainer.getChildren().add(vBox);
vBox.heightProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("Height changed to: " + newValue.doubleValue());
    if(newValue.doubleValue() > 100)
    {
        //do something!
    }
});
for (int i = 0; i < 5; i++) {
    vBox.getChildren().add(new Label("newLabel"));
}
Button button = new Button("Add Label");
button.setOnAction(event -> {
    vBox.getChildren().add(new Label("newLabel"));
});
Button checkButton = new Button("Print VBox Height");
checkButton.setOnAction(event -> System.out.println("VBox Height:" + vBox.getHeight()));

vBoxContainer.getChildren().addAll(button, checkButton);
stage.setScene(new Scene(vBoxContainer));
stage.show();
SedJ601
  • 12,173
  • 3
  • 41
  • 59
4

requestLayout does not actually do a layout pass. It simply tells JavaFX, that a layout pass is required which will result in JavaFX doing the layout pass some time after your method returns. To do the layout yourself, you need to call layout yourself, i.e. change the logic in the event handler like this:

button.setOnAction(event -> {
    System.out.println("Height Before new Label:"+vBox.getHeight());
    vBox.getChildren().add(new Label("newLabel"));

    // manually doing layout on the root here
    vBoxContainer.applyCss();
    vBoxContainer.layout();

    System.out.println("Height After new Label:"+vBox.getHeight());
});

Note that I do the layout pass for the root, since the ancestor layouts can also be involved in determining the actual size of a Node...

fabian
  • 80,457
  • 12
  • 86
  • 114