Understanding Layout

Scott Palmer swpalmer at gmail.com
Thu Dec 18 21:49:16 UTC 2014


Short Version:

Is there good documentation on how JavaFX performs layout? (Not specific
layouts, but layout in general.)


Long Version:

I was looking into a layout issue in ControlsFX (BreadCrumbBar width is
reported incorrectly and it doesn't behave when right-aligned).

What I found is that Parent and SkinBase assume that layout has already
occurred on child nodes when computing the preferred width/height.  The
JavaDocs indicate this is a known assumption:

     * Calculates the preferred width of this {@code SkinBase}. The default
     * implementation calculates this width as the width of the area
occupied
     * by its managed children when they are positioned at their
     * current positions at their preferred widths.

Parent.computePrefWidth(double height) javadocs contain the exact same
comment.

Note however that the Region class documents Region.computePrefWidth(double
height) differently.  It simply states:

     * Computes the preferred width of this region for the given height.
     * Region subclasses should override this method to return an
appropriate
     * value based on their content and layout strategy.  If the subclass
     * doesn't have a VERTICAL content bias, then the height parameter can
be
     * ignored.

Node.prefWidth(double height), which is what
Control.computePrefWidth(double height) delegates to if there is no
SkinBase, clearly states:
 "Returns the node's preferred width for use in layout calculations."

It's the "for use in layout calculations" part, combined with the fact that
prefWidth relies on the layout having already happened, that confuses me.

Clearly layout is working in most cases, so this must all work out in the
general case.  But as I understand it layout happens top-down, so
constraints imposed by the parent container must be accounted for when
positioning and sizing the children.  That implies that the child nodes are
not yet laid out when their preferred size is queried.

I fixed the issues I was having with BreadCrumbBar by overriding the
implementation of computePrefWidth(double height) with one that does not
care about the current X position of the child Nodes.  It still relies on
the layout bounds via Node.prefWidth(double height), and duplicates some of
the calculations that an actual layout will do, but it worked to solve the
problems of right-aligned layout and a widthProperty that was clearly lying.

I feel like I am missing something fundamental about how Layout works
though.
Is there documentation that explains the general layout algorithm and how
to make sense of the apparent circular dependency?

Regards,

Scott


More information about the openjfx-dev mailing list