Provides classes to support user interface layout. Each layout pane class supports a different layout strategy for its children and applications may nest these layout panes to achieve the needed layout structure in the user interface. Once a node is added to one of the layout panes, the pane will automatically manage the layout for the node, so the application should not position or resize the node directly; see "Node Resizability" for more details.
The scene graph layout mechanism is driven automatically by the system once the application creates and displays a {@link javafx.scene.Scene Scene}. The scene graph detects dynamic node changes which affect layout (such as a change in size or content) and calls {@code requestLayout()}, which marks that branch as needing layout so that on the next pulse, a top-down layout pass is executed on that branch by invoking {@code layout()} on that branch's root. During that layout pass, the {@code layoutChildren()} callback method will be called on each parent to layout its children. This mechanism is designed to maximize layout efficiency by ensuring multiple layout requests are coalesced and processed in a single pass rather than executing re-layout on on each minute change. Therefore, applications should not invoke layout directly on nodes.
The scene graph supports both resizable and non-resizable node classes. The {@code isResizable()} method on {@link javafx.scene.Node Node} returns whether a given node is resizable or not. {@literal A resizable node class is one which supports a range of acceptable sizes (minimum <= preferred <= maximum), allowing its parent to resize it within that range during layout, given the parent's own layout policy and the layout needs of sibling nodes.} Node supports the following methods for layout code to determine a node's resizable range:
public Orientation getContentBias()
public double minWidth(double height)
public double minHeight(double width)
public double prefWidth(double height)
public double prefHeight(double width)
public double maxWidth(double height)
public double maxHeight(double width)
Non-resizable node classes, on the other hand, do not have a consistent resizing API and so are not resized by their parents during layout. Applications must establish the size of non-resizable nodes by setting appropriate properties on each instance. These classes return their current layout bounds for min, pref, and max, and the {@code resize()} method becomes a no-op.
Resizable classes: {@link javafx.scene.layout.Region Region}, {@link javafx.scene.control.Control Control}, {@link javafx.scene.web.WebView WebView}
Non-Resizable classes: {@link javafx.scene.Group Group}, {@link javafx.scene.shape.Shape Shape}, {@link javafx.scene.text.Text Text}
For example, a Button control (resizable) computes its min, pref, and max sizes which its parent will use to resize it during layout, so the application only needs to configure its content and properties:
Button button = new Button("Apply");
However, a Circle (non-resizable) cannot be resized by its parent, so the application
needs to set appropriate geometric properties which determine its size:
Circle circle = new Circle();
circle.setRadius(50);
For example, to override the preferred size of a ListView:
listview.setPrefSize(200,300);
Or, to change the max width of a button so it will resize wider to fill a space:
button.setMaxWidth(Double.MAX_VALUE);
For the inverse case, where the application needs to clamp the node's min or max size to its preferred:
listview.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
And finally, if the application needs to restore the intrinsically computed values:
listview.setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
These two bounds properties will often differ for a given node and {@code layoutBounds} is computed differently depending on the node class:
Node Type | Layout Bounds |
---|---|
{@link javafx.scene.shape.Shape Shape},{@link javafx.scene.image.ImageView ImageView} | Includes geometric bounds (geometry plus stroke). Does NOT include effect, clip, or any transforms. |
{@link javafx.scene.text.Text Text} | logical bounds based on the font height and content width, including white space. can be configured to be tight bounds around chars glyphs by setting {@code boundsType}. Does NOT include effect, clip, or any transforms. |
{@link javafx.scene.layout.Region Region}, {@link javafx.scene.control.Control Control}, {@link javafx.scene.web.WebView WebView} | always {@code [0,0 width x height]} regardless of visual bounds, which might be larger or smaller than layout bounds. |
{@link javafx.scene.Group Group} | Union of all visible children's visual bounds ({@code boundsInParent}) Does NOT include effect, clip, or transforms set directly on group, however DOES include effect, clip, transforms set on individual children since those are included in the child's {@code boundsInParent}. |
So for example, if a {@link javafx.scene.effect.DropShadow DropShadow} is added to a shape, that shadow will not be factored into layout by default. Or, if a {@link javafx.animation.ScaleTransition ScaleTransition} is used to pulse the size of a button, that pulse animation will not disturb layout around that button. If an application wishes to have the effect, clip, or transform factored into the layout of a node, it should wrap that node in a Group.