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