Circling back to a new layout algorithm
Kevin Rushforth
kevin.rushforth at oracle.com
Sat Nov 13 00:48:00 UTC 2021
I think this will be a good improvement to implement to the JavaFX
layout algorithm. I see that you filed JDK-8276671 [1] to track this
enhancement.
As noted, the main concern will be making sure we don't break existing
applications, so testing this will be key.
One other issue that will need to be addressed is what a good the
threshold would be for the maximum number of iterations, such that if it
doesn't converge we will stop anyway (and log a warning). This is a
trade-off between performance and accuracy, although as noted in the JBS
issue, if the layout doesn't converge it's a bug. The value we
ultimately choose can be discussed during the review and testing.
Regardless of what the threshold is, I recommend a system property
(named something like "com.sun.javafx.scene.layout.threshold"). This
will be helpful during testing.
What do other developers think? Would this be a useful problem to solve
in layout?
-- Kevin
[1] https://bugs.openjdk.java.net/browse/JDK-8276671
On 11/4/2021 7:31 PM, Michael Strauß wrote:
> I previously proposed a new iterative layout algorithm [1] that
> supports baseline alignment and introduces new APIs to give developers
> control over the way nodes are aligned. This is a solution to the
> long-standing problem that JavaFX cannot reliably lay out nodes that
> are aligned on their baseline [2]. The new layout algorithm might also
> fix some issues where the scene graph layout only settles after
> interacting with the controls (for example, by clicking).
>
> I've created a small application that shows the new APIs and a
> correctly working baseline-aligned layout [3]. In addition to that, I
> also built SceneBuilder with both the old and new layout system, and
> played around with it to find out whether there were any regressions
> or visual differences. So far, I haven't found any.
>
> In order to move this forward, I think it would be a good idea to test
> the latest version of the new layout system in more real-world JavaFX
> applications. Any help from JavaFX application developers is greatly
> appreciated. It's as easy as checking out the JavaFX sources from the
> PR [1], building a local SDK and linking your application with the
> binaries.
>
>
> Finally, here's a high-level overview of the new algorithm:
>
> When Parent::layout() is called on a layout root (i.e. a scene root or
> an unmanaged node), it will lay out its children in a loop until the
> scene graph under the layout root is fully laid out, which means it is
> clean and doesn't require further layout. The totality of layout
> activity for a single layout root is called "layout cycle". A layout
> cycle will often take a few layout passes to finish (but not more than
> 2 in most cases). There is no limit on how often Parent::layout() will
> iterate to lay out its children, so in principle, this could lead to
> an infinite layout loop.
>
> One source of infinite layout loops are incorrectly implemented controls:
>
> class PathologicalControl extends Region {
> final Text text = new Text("foo");
>
> PathologicalControl() {
> getChildren().add(text);
> }
>
> @Override
> protected void layoutChildren() {
> text.relocate(0, text.getLayoutY() + 10);
> }
> }
>
> In this example, each call to layoutChildren() moves down the text
> node another 10 pixels from where it was, which causes the layout
> algorithm to schedule yet another layout pass. It's an infinite loop.
>
> The layout system detects this by tracking how often a node
> invalidates the scene graph in a single layout cycle. If a node
> exceeds a threshold of 100 invalidations, it will be suspended from
> layout and can no longer invalidate the scene graph in the current
> layout cycle. A warning will be logged to notify developers of that
> fact.
>
>
> [1] https://github.com/openjdk/jfx/pull/433
> [2] https://bugs.openjdk.java.net/browse/JDK-8090261
> [3] https://github.com/mstr2/jfx-layout-sample
More information about the openjfx-dev
mailing list