I'm using a Text
node to compute the dimensions of a string, as described here, summarized as:
new Text("some text").getLayoutBounds();
The dimensions returned are not always the same at different execution points, for the same input string, and everything else being the same (font, etc.). It seems that the inconsistencies are somehow related to the interaction of the backspace with a TextArea
, even if this TextArea is not related to the Text node.
It's an intermittent/non-deterministic problem, but others were able to reproduce it with the following code:
public class Test extends Application {
private Text text = new Text();
public static void main(String... args) {
launch(args);
}
public void start(Stage stage) {
TextArea textArea = new TextArea();
textArea.textProperty().addListener((observable, oldValue, newValue) -> {
text.setText(newValue);
System.out.println(String.format("height=%.1f", text.getLayoutBounds().getHeight()));
});
stage.setScene(new Scene(new Group(textArea)));
stage.show();
}
}
Typing a few "X" characters, I get (on Windows): height=16.0
. After typing backspace (but when there are still a few "X" characters in the string), I get height=17.0
. If I type some more characters, the height stays 17.0
, then arbitrarily shifts back to 16.0, then 17.0, etc. Other users report different kinds of erratic behavior.
- If you replace the
TextArea
withTextField
, the problem goes away (!) - It doesn't matter where the
Text
node is initialized. - While debugging, I see that that the
valid
flag isfalse
in all cases inLazyBoundsProperty#get
, so bounds seem to be recomputed for each new character. - I get the same behavior on JavaFX 11.0.2 as JavaFX 16.
What causes this inconsistency, and how can I avoid it?