On Mon, 29 Jan 2024 14:38:20 GMT, John Hendrikx <jhendr...@openjdk.org> wrote:
>> There are a number of tickets open related to text rendering: >> >> https://bugs.openjdk.org/browse/JDK-8314215 >> >> https://bugs.openjdk.org/browse/JDK-8145496 >> >> https://bugs.openjdk.org/browse/JDK-8129014 >> >> They have in common that wrapped text is taking the trailing spaces on each >> wrapped line into account when calculating where to wrap. This looks okay >> for text that is left aligned (as the spaces will be trailing the lines and >> generally aren't a problem, but looks weird with CENTER and RIGHT >> alignments. Even with LEFT alignment there are artifacts of this behavior, >> where a line like `AAA BBB CCC` (note the **double** spaces) gets split up >> into `AAA `, `BBB ` and `CCC`, but if space reduces further, it will wrap >> **too** early because the space is taken into account (ie. `AAA` may still >> have fit just fine, but `AAA ` doesn't, so the engine wraps it to `AA` + `A >> ` or something). >> >> The fix for this is two fold; first the individual lines of text should not >> include any trailing spaces into their widths; second, the code that is >> taking the trailing space into account when wrapping should ignore all >> trailing spaces (currently it is ignoring all but one trailing space). With >> these two fixes, the layout in LEFT/CENTER/RIGHT alignments all look great, >> and there is no more early wrapping due to a space being taking into account >> while the actual text still would have fit (this is annoying in tight >> layouts, where a line can be wrapped early even though it looks like it >> would have fit). >> >> If it were that simple, we'd be done, but there may be another issue here >> that needs solving: wrapped aligned TextArea's. >> >> TextArea don't directly support text alignment (via a setTextAlignment >> method like Label) but you can change it via CSS. >> >> For Left alignment + wrapping, TextArea will ignore any spaces typed before >> a line that was wrapped. In other words, you can type spaces as much as you >> want, and they won't show up and the cursor won't move. The spaces are all >> getting appended to the previous line. When you cursor through these >> spaces, the cursor can be rendered out of the control's bounds. To >> illustrate, if you have the text `AAA BBB CCC`, and the text >> gets wrapped to `AAA`, `BBB`, `CCC`, typing spaces before `BBB` will not >> show up. If you cursor back, the cursor may be outside the control bounds >> because so many spaces are trailing `AAA`. >> >> The above behavior has NOT changed, is pretty standard for wrapped text >> controls,... > > John Hendrikx has updated the pull request incrementally with one additional > commit since the last revision: > > Move test that needs QuantumToolkit to system tests MonkeyTester won't start: Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: Index 44 out of bounds for length 38 at javafx.graphics/com.sun.javafx.text.TextRun.getAdvance(TextRun.java:362) at javafx.graphics/com.sun.javafx.text.PrismTextLayout.computeTrailingSpaceWidth(PrismTextLayout.java:1049) at javafx.graphics/com.sun.javafx.text.PrismTextLayout.createLine(PrismTextLayout.java:1017) at javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1333) at javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:231) at javafx.graphics/com.sun.javafx.text.PrismTextLayout.getVisualBounds(PrismTextLayout.java:1461) at javafx.graphics/javafx.scene.text.Text.getVisualBounds(Text.java:424) at javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1191) at javafx.graphics/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:150) at javafx.graphics/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117) at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3845) at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3807) at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3755) at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3909) at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3701) at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1849) at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1710) at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1649) at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1502) at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115) at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117) at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3845) at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3807) at javafx.graphics/javafx.scene.Node.doComputeLayoutBounds(Node.java:3655) at javafx.graphics/javafx.scene.Node$1.doComputeLayoutBounds(Node.java:449) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBoundsImpl(NodeHelper.java:168) at javafx.graphics/com.sun.javafx.scene.GroupHelper.computeLayoutBoundsImpl(GroupHelper.java:63) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBounds(NodeHelper.java:108) at javafx.graphics/javafx.scene.Node$3.computeBounds(Node.java:3507) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9793) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:1) at javafx.graphics/javafx.scene.Node.getLayoutBounds(Node.java:3522) at javafx.controls/javafx.scene.control.skin.ScrollPaneSkin$1.invalidated(ScrollPaneSkin.java:163) at javafx.base/javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:82) at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:80) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.invalidate(Node.java:9803) at javafx.graphics/javafx.scene.Node.layoutBoundsChanged(Node.java:3678) at javafx.graphics/javafx.scene.Node.doNotifyLayoutBoundsChanged(Node.java:4071) at javafx.graphics/javafx.scene.Node$1.doNotifyLayoutBoundsChanged(Node.java:476) at javafx.graphics/com.sun.javafx.scene.NodeHelper.notifyLayoutBoundsChangedImpl(NodeHelper.java:190) at javafx.graphics/com.sun.javafx.scene.NodeHelper.notifyLayoutBoundsChanged(NodeHelper.java:143) at javafx.graphics/javafx.scene.Node.doGeomChanged(Node.java:4024) at javafx.graphics/javafx.scene.Node$1.doGeomChanged(Node.java:471) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChangedImpl(NodeHelper.java:186) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChanged(NodeHelper.java:139) at javafx.graphics/javafx.scene.Parent.childBoundsChanged(Parent.java:1874) at javafx.graphics/javafx.scene.Node.notifyParentOfBoundsChange(Node.java:4096) at javafx.graphics/javafx.scene.Node.transformedBoundsChanged(Node.java:4057) at javafx.graphics/javafx.scene.Node.localBoundsChanged(Node.java:4039) at javafx.graphics/javafx.scene.Node.doGeomChanged(Node.java:4025) at javafx.graphics/javafx.scene.Node$1.doGeomChanged(Node.java:471) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChangedImpl(NodeHelper.java:186) at javafx.graphics/com.sun.javafx.scene.shape.TextHelper.geomChangedImpl(TextHelper.java:105) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChanged(NodeHelper.java:139) at javafx.graphics/javafx.scene.text.Text.needsTextLayout(Text.java:268) at javafx.graphics/javafx.scene.text.Text$8.invalidated(Text.java:679) at javafx.base/javafx.beans.property.DoublePropertyBase.markInvalid(DoublePropertyBase.java:113) at javafx.base/javafx.beans.property.DoublePropertyBase$Listener.invalidated(DoublePropertyBase.java:261) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.binding.DoubleBinding.invalidate(DoubleBinding.java:232) at javafx.base/com.sun.javafx.binding.BindingHelperObserver.invalidated(BindingHelperObserver.java:52) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.binding.ObjectBinding.invalidate(ObjectBinding.java:192) at javafx.base/javafx.beans.Observable.lambda$0(Observable.java:125) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:106) at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113) at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147) at javafx.controls/javafx.scene.control.ScrollPane.setViewportBounds(ScrollPane.java:568) at javafx.controls/javafx.scene.control.skin.ScrollPaneSkin.layoutChildren(ScrollPaneSkin.java:607) at javafx.controls/javafx.scene.control.Control.layoutChildren(Control.java:612) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1208) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:595) at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2601) at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$2(Toolkit.java:401) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:598) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:578) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:571) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$11(QuantumToolkit.java:352) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 2 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) at java.base/java.util.Objects.checkIndex(Objects.java:385) at java.base/java.util.ArrayList.get(ArrayList.java:427) at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:88) at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:314) at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1705) at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1649) at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1502) at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115) at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117) at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3845) at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3807) at javafx.graphics/javafx.scene.Node.doComputeLayoutBounds(Node.java:3655) at javafx.graphics/javafx.scene.Node$1.doComputeLayoutBounds(Node.java:449) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBoundsImpl(NodeHelper.java:168) at javafx.graphics/com.sun.javafx.scene.GroupHelper.computeLayoutBoundsImpl(GroupHelper.java:63) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBounds(NodeHelper.java:108) at javafx.graphics/javafx.scene.Node$3.computeBounds(Node.java:3507) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9793) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:1) at javafx.base/javafx.beans.binding.ObjectExpression.getValue(ObjectExpression.java:49) at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:367) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:80) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.invalidate(Node.java:9803) at javafx.graphics/javafx.scene.Node.layoutBoundsChanged(Node.java:3678) at javafx.graphics/javafx.scene.Node.doNotifyLayoutBoundsChanged(Node.java:4071) at javafx.graphics/javafx.scene.Node$1.doNotifyLayoutBoundsChanged(Node.java:476) at javafx.graphics/com.sun.javafx.scene.NodeHelper.notifyLayoutBoundsChangedImpl(NodeHelper.java:190) at javafx.graphics/com.sun.javafx.scene.NodeHelper.notifyLayoutBoundsChanged(NodeHelper.java:143) at javafx.graphics/javafx.scene.Node.doGeomChanged(Node.java:4024) at javafx.graphics/javafx.scene.Node$1.doGeomChanged(Node.java:471) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChangedImpl(NodeHelper.java:186) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChanged(NodeHelper.java:139) at javafx.graphics/javafx.scene.Parent.childBoundsChanged(Parent.java:1874) at javafx.graphics/javafx.scene.Node.notifyParentOfBoundsChange(Node.java:4096) at javafx.graphics/javafx.scene.Node.transformedBoundsChanged(Node.java:4057) at javafx.graphics/javafx.scene.Node.localBoundsChanged(Node.java:4039) at javafx.graphics/javafx.scene.Node.doGeomChanged(Node.java:4025) at javafx.graphics/javafx.scene.Node$1.doGeomChanged(Node.java:471) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChangedImpl(NodeHelper.java:186) at javafx.graphics/com.sun.javafx.scene.shape.TextHelper.geomChangedImpl(TextHelper.java:105) at javafx.graphics/com.sun.javafx.scene.NodeHelper.geomChanged(NodeHelper.java:139) at javafx.graphics/javafx.scene.text.Text.needsTextLayout(Text.java:268) at javafx.graphics/javafx.scene.text.Text$8.invalidated(Text.java:679) at javafx.base/javafx.beans.property.DoublePropertyBase.markInvalid(DoublePropertyBase.java:113) at javafx.base/javafx.beans.property.DoublePropertyBase$Listener.invalidated(DoublePropertyBase.java:261) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.binding.DoubleBinding.invalidate(DoubleBinding.java:232) at javafx.base/com.sun.javafx.binding.BindingHelperObserver.invalidated(BindingHelperObserver.java:52) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.binding.ObjectBinding.invalidate(ObjectBinding.java:192) at javafx.base/javafx.beans.Observable.lambda$0(Observable.java:125) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91) at javafx.base/javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:106) at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:113) at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147) at javafx.controls/javafx.scene.control.ScrollPane.setViewportBounds(ScrollPane.java:568) at javafx.controls/javafx.scene.control.skin.ScrollPaneSkin.layoutChildren(ScrollPaneSkin.java:607) at javafx.controls/javafx.scene.control.Control.layoutChildren(Control.java:612) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1208) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:595) at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2601) at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$2(Toolkit.java:401) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:598) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:578) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:571) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$11(QuantumToolkit.java:352) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 2 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302) at java.base/java.util.Objects.checkIndex(Objects.java:385) at java.base/java.util.ArrayList.get(ArrayList.java:427) at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:88) at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:314) at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1705) at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1649) at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1502) at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115) at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117) at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3845) at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3807) at javafx.graphics/javafx.scene.Node.doComputeLayoutBounds(Node.java:3655) at javafx.graphics/javafx.scene.Node$1.doComputeLayoutBounds(Node.java:449) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBoundsImpl(NodeHelper.java:168) at javafx.graphics/com.sun.javafx.scene.GroupHelper.computeLayoutBoundsImpl(GroupHelper.java:63) at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeLayoutBounds(NodeHelper.java:108) at javafx.graphics/javafx.scene.Node$3.computeBounds(Node.java:3507) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9793) at javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:1) at javafx.graphics/javafx.scene.Node.getLayoutBounds(Node.java:3522) at javafx.graphics/javafx.scene.Node.relocate(Node.java:2872) at javafx.controls/javafx.scene.control.skin.ScrollPaneSkin$6.layoutChildren(ScrollPaneSkin.java:700) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1208) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215) at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:595) at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2601) at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$2(Toolkit.java:401) at java.base/java.security.AccessController.doPrivileged(AccessController.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400) at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:598) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:578) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:571) at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$11(QuantumToolkit.java:352) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) ------------- PR Comment: https://git.openjdk.org/jfx/pull/1236#issuecomment-1915062973