Example code below. This outputs all zeros for everything. For ToolBar, it also shows zeros. For Text, it outputs non-zero width and height. Is this a bug on Label, or deliberate? Am I supposed to do something to get Label to have its bounds? I have tried other threads, moving, various things.
Note: all the Nodes do show up as expected. It's just the getting of the Bounds that isn't working.
I saw something about maybe using a listener on the boundsInParent property. When I try that, the numbers bounce around some across many events, so there doesn't appear to be a way to figure out when I would have the right values.
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class TestBounds extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
Pane root = new Pane();
Group g = new Group();
root.getChildren().add(g);
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();
Platform.runLater(() -> {
// Text text = new Text("test label");
// ToolBar text = new ToolBar(new Button("test label"));
Label text = new Label("test label");
g.getChildren().add(text);
System.out.println(text.getBoundsInParent());
System.out.println(text.getBoundsInLocal());
System.out.println(text.getLayoutBounds());
});
}
}
@sarcan's answer is a good start, but it's incomplete. Here is an example:
package other;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class Main extends Application {
@Override
public void start(Stage stage) {
Pane root = new Pane();
final Group g = new Group();
root.getChildren().add(g);
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();
Platform.runLater(() -> {
final Label text = new Label("test label");
g.getChildren().add(text);
new Thread(() -> {
Platform.runLater(() -> {
System.out.println("text.getWidth() = " + text.getWidth());
System.out.println(text.getBoundsInParent());
System.out.println(text.getBoundsInLocal());
System.out.println(text.getLayoutBounds());
});
}).start();
});
}
public static void main(String[] args) {
launch(args);
}
}
You can remove the new Thread() part and it will still show the problem. I threw that in there just to show I was really trying to "defer" it as was recommended. The above example uses the runLater as recommended, but still demonstrates the problem. The bounds are all output as 0's.
The above example is very common--adding a Node when already in the FX thread and needing access to its bounds. But how does one reliably defer so you can get those bounds after the scene has been updated? Platform.runLater apparently does not do it.