-
Notifications
You must be signed in to change notification settings - Fork 139
Description
Description
The boundaries of nodes can jump around when some of their text properties are edited.
This is caused by the value of FontMetrics#getDimension being inconsistent, namely, it returns different values for the same input string at different points in the execution of the program. This inconsistency seems to be caused by the bounds of the Text node used to compute the text dimensions being erratically recomputed within JavaFX. Debugging shows that the valid flag in LazyBoundsProperty#get is unpredictably true or false, leading to the correct value when it is false, and some slightly lower and incorrect value when it is true. For some reason, hitting "backspace" when editing a node invalidates the cached value. This is all very mysterious.
This appears to be Windows-specific, as the bug is not reproducible on MacOS.
Steps to reproduce
In user mode:
- Create new class diagram
- Create a new note node
- Add and remove characters over multiple lines, using backspace
- Notice the node bounds move around slightly.
In development mode:
- Add the following line in
FontMetrics#getDimension, below the lineBounds bounds = aTextNode.getLayoutBounds();:
System.out.println(String.format("height=%.1f", bounds.getHeight()));
- Create new class diagram
- Create a new note node
- Type "XXXXXX" in the node's text property, notice a first value (
16.0in Windows with default fonts). - Type backspace, notice a different value (
17.0in Windows) - Type more "X" characters, notice the value eventually reverts to the initial one (16).
Configuration
- JetUML Release: at least 3.0
- OS + version: Windows
- Java version: 14.0.1
- JavaFX version: 11.0.2
Additional Information
This issue is not mentioned in the relevant Stack Overflow post, and in fact running the basic example below does not reproduce the bug, so it's due to some deeper interaction.
public class Test extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
TextField field = new TextField();
field.setOnAction( e -> {
Text text = new Text(field.getText());
System.out.println(text.getLayoutBounds());
} );
HBox hbox = new HBox(field);
stage.setScene(new Scene(hbox));
stage.show();
}
}