“ I've changed the default alignment for
Label to TOP_LEFT (the default alignment of the base class Labeled is
CENTER_LEFT).”

How can you do that without breaking things?  Even though it may be uncommon to 
set minHeight or prefHeight, that isn’t the point.  It still breaks existing 
code.

Scott

> On Apr 16, 2021, at 12:48 AM, Michael Strauß <michaelstr...@gmail.com> wrote:
> 
> I've learned a few new things while working on the proposed new layout
> algorithm, and added a few new APIs:
> 
> 
> 1. A central concept of the new algorithm was the notion of a
> text-baseline node, indicated by Node::isTextBaseline(). I've come to
> realize that this property should percolate upwards in the scene
> graph: if a node has a text-baseline, the node's parent should also be
> considered to have a text-baseline. Adding this new behavior works
> surprisingly well and produces very intuitive layout results.
> 
> 
> 2. The default behavior of all layout containers is to pick the first
> text-baseline child to derive their own baseline offset. I've added
> Node::prefBaselineProperty(), which makes it possible to override this
> default selection: layout containers now pick the first child that
> reports Node::isPrefBaseline(), and only if there is no such child,
> they fall back to Node::isTextBaseline(). Developers can use this
> property to fine-tune their baseline layouts.
> 
> 
> 3. Optimization: Controls that contain text will often consist of a
> container of some sort and a javafx.scene.text.Text node within it.
> Computing the baseline offset of such a control is very easy with the
> new layout algorithm:
> 
> public double getBaselineOffset() {
>    return text.getLayoutBounds().getMinY() + text.getLayoutY() +
> text.getBaselineOffset();
> }
> 
> This works because changing text.layoutY will automatically schedule
> another layout pass for all of its parents. Re-layouting all parents
> is necessary because changing layoutY can change the effective
> baseline offset, and changing the baseline offset of any node can have
> layout implications on any of its parents.
> 
> However, when we consider the Label control (which is probably among
> the most commonly used controls), this can be a bit excessive. Label
> controls are often used to display pure text, and as such, we can
> often "know" the baseline offset without actually needing to schedule
> a second layout pass. This assumption is only correct if the text
> within the Label is top-aligned (because if it isn't, the Label
> baseline offset can not be known in advance of an actual layout pass).
> 
> To leverage this assumption, I've changed the default alignment for
> Label to TOP_LEFT (the default alignment of the base class Labeled is
> CENTER_LEFT). In most cases, there will be no visual difference
> anyway, because I imagine Label controls will seldomly be set to a
> minHeight or prefHeight.
> 
> This specific scenario will enable an optimization where the first
> layout pass of Label will not schedule a second layout pass. It might
> be possible to find more such scenarios that can benefit from
> fast-path optimizations.
> 
> 
> 4. In order to get a better understanding of the layout process, I
> added additional logging to track layout passes. Then I compared the
> current algorithm with the new algorithm by tracking the initial
> layout after starting a sample program (i.e. all layout activity until
> the first frame is rendered). In the following log, "cumulative layout
> passes" means how often layoutChildren() has been invoked on any of
> the scene graph nodes. The actual log output includes a tree
> visualization of the entire scene graph that is being layouted, which
> I've removed for the sake or brevity.
> 
> Current algorithm log output:
> INFO: Layouting VBox (triggered by scene out-of-pulse), cumulative
> layout passes: 49
> INFO: Layouting VBox (triggered by scene pulse), cumulative layout passes: 43
> INFO: Layouting VBox (triggered by scene pulse), cumulative layout passes: 0
> 
> New algorithm log output:
> INFO: Layouting VBox (triggered by scene out-of-pulse), cumulative
> layout passes: 86
> INFO: Layouting VBox (triggered by scene pulse), cumulative layout passes: 19
> 
> A major difference is that the current algorithm will often leave the
> scene graph in a 'dirty' layout state after running a complete layout
> cycle, which necessitates another layout cycle as part of the next
> pulse. The new algorithm, however, leaves the scene graph in a clean
> layout state after a complete cycle, which takes more work at first,
> but saves work that would otherwise be done in the next pulse.
> 
> 
> 5. Since the new layout algorithm will leave the scene graph in a
> clean state, it is not necessary to repeatedly layout the same thing
> (like in Node::doLayoutPass()). Cases like these should be identified
> and may be changed to single layout invocations.
> 
> 
> Overall, I think there's good reason to assume that the proposed
> algorithm works and that it produces consistent results for
> application developers. At this point it would be useful to know
> whether or not to continue with the effort.

Reply via email to