Class Layout.ForFlowLayout
- All Implemented Interfaces:
Layout
- Enclosing interface:
Layout
Layout implementation that configures and installs a
ResponsiveGridFlowLayout onto a component. It holds:
- Alignment (
align) — the horizontal alignment of components within each row of the flow (left, center, right, leading, or trailing). - Horizontal gap (
hgap) — the pixel spacing between components in the same row. - Vertical gap (
vgap) — the pixel spacing between rows. - Per-child
FlowCellconstraints (childConstraints) — a sortedAssociationmapping child indices (Integer) toFlowCells that are pushed onto the component's direct children. Unlike a positional tuple, the association is sparse: you only need to include entries for the children you actually want to configure. EachFlowCellcarries a responsive span policy (seeUILayoutConstants.AUTO_SPAN(Configurator)) that theResponsiveGridFlowLayoutqueries on every layout pass to determine how many grid columns a child should occupy for the current parent size.
The child-constraint tuple is the key to building fully reactive responsive
layouts. With the static UI.AUTO_SPAN() approach every child's span policy
is fixed at the time the component is added. When child constraints need to change
at runtime (e.g. the number of columns depends on application state), wrap a
Layout.ForFlowLayout in a Var and pass it to
UIForAnySwing.withLayout(sprouts.Val):
import static swingtree.UI.*;
// ...
Var<Layout> layout = Var.of(
Layout.flow( AUTO_SPAN(it -> it.small(12).medium(6)),
AUTO_SPAN(it -> it.small(12).medium(6)) )
);
UI.panel()
.withLayout(layout)
.add( label("A") )
.add( label("B") );
// Later: swap to a single full-width column for both children:
layout.set( Layout.flow( AUTO_SPAN(12), AUTO_SPAN(12) ) );
Changing the layout property triggers a style re-evaluation, which calls
installFor(JComponent), which re-pushes the updated FlowCells as
client properties onto the children so that the next layout pass picks them up.
Instances are created via the Layout.flow() family of factory methods and
are further configured through the fluent with* wither methods.
-
Nested Class Summary
Nested classes/interfaces inherited from interface swingtree.api.Layout
Layout.BorderLayoutInstaller, Layout.ForBoxLayout, Layout.ForFlowLayout, Layout.ForMigLayout, Layout.GridLayoutInstaller, Layout.None, Layout.Unspecific -
Method Summary
Modifier and TypeMethodDescriptionbooleaninthashCode()voidinstallFor(JComponent component) Installs aResponsiveGridFlowLayoutonto the supplied component and applies all constraints stored in this configuration.toString()withAddedChildConstraint(Configurator<FlowCellConf> cellConfig) Returns a newLayout.ForFlowLayoutwith aFlowCellbuilt from the suppliedConfiguratorlambda appended to the end of the existing child-constraint tuple.withAddedChildConstraint(FlowCell childConstraint) Returns a newLayout.ForFlowLayoutwith the suppliedFlowCellappended to the end of the existing child-constraint tuple.Returns a newLayout.ForFlowLayoutwith the given horizontal alignment and all other properties copied unchanged.withChildConstraint(int index, Configurator<FlowCellConf> cellConfig) Returns a newLayout.ForFlowLayoutwith theFlowCellat the given child index replaced by one built from the suppliedConfiguratorlambda.withChildConstraint(int index, FlowCell childConstraint) Returns a newLayout.ForFlowLayoutwith theFlowCellat the given child index replaced by the supplied value.withChildConstraints(sprouts.Association<Integer, FlowCell> childConstraints) Returns a newLayout.ForFlowLayoutwhose per-childFlowCellconstraints are replaced by the supplied sortedAssociation.withChildConstraints(FlowCell... childConstraints) Returns a newLayout.ForFlowLayoutwhose per-childFlowCellconstraints are replaced by the supplied varargs array.withHorizontalGap(int hgap) Returns a newLayout.ForFlowLayoutwith the given horizontal gap size and all other properties copied unchanged.withVerticalGap(int vgap) Returns a newLayout.ForFlowLayoutwith the given vertical gap size and all other properties copied unchanged.
-
Method Details
-
withAlignment
Returns a newLayout.ForFlowLayoutwith the given horizontal alignment and all other properties copied unchanged.- Parameters:
align- The new horizontal alignment for the flow.- Returns:
- A new
Layout.ForFlowLayoutwith the updated alignment.
-
withHorizontalGap
Returns a newLayout.ForFlowLayoutwith the given horizontal gap size and all other properties copied unchanged.- Parameters:
hgap- The new horizontal gap between components, in pixels.- Returns:
- A new
Layout.ForFlowLayoutwith the updated horizontal gap.
-
withVerticalGap
Returns a newLayout.ForFlowLayoutwith the given vertical gap size and all other properties copied unchanged.- Parameters:
vgap- The new vertical gap between component rows, in pixels.- Returns:
- A new
Layout.ForFlowLayoutwith the updated vertical gap.
-
withChildConstraints
public Layout.ForFlowLayout withChildConstraints(sprouts.Association<Integer, FlowCell> childConstraints) Returns a newLayout.ForFlowLayoutwhose per-childFlowCellconstraints are replaced by the supplied sortedAssociation.Keys are child indices (
0= first child,1= second, etc.); the association is sparse, so you only need to include entries for children you actually want to configure. Children whose index has no entry keep whateverFlowCellthey already have. An empty association means no constraints are stored in this layout object; anyAddConstraintclient properties previously pushed to children by an earlierinstallForcall remain on those children until explicitly overwritten.
The intended way of creatingFlowCells is by usingUILayoutConstants.AUTO_SPAN(Configurator)!
An important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
childConstraints- The positionalFlowCellconstraints for the children.- Returns:
- A new
Layout.ForFlowLayoutwith the updated child constraints.
-
withChildConstraints
Returns a newLayout.ForFlowLayoutwhose per-childFlowCellconstraints are replaced by the supplied varargs array.The constraints are mapped positionally to the component's children: the first argument applies to the first child, the second to the second, and so on. Passing an empty array stores no constraints in this layout object; any
AddConstraintclient properties previously pushed to children by an earlierinstallForcall remain on those children until explicitly overwritten.FlowCellinstances are most conveniently created viaUILayoutConstants.AUTO_SPAN(Configurator):
The intended way of creatingimport static swingtree.UI.*; // ... Layout.flow() .withChildConstraints( AUTO_SPAN( it -> it.small(12).medium(6) ), AUTO_SPAN( it -> it.small(12).medium(6) ) )FlowCells is through theUILayoutConstants.AUTO_SPAN(Configurator)factory method!
An important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any size specific span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
childConstraints- TheFlowCellconstraints to apply to the component's children in child-index order.- Returns:
- A new
Layout.ForFlowLayoutwith the updated child constraints.
-
withChildConstraint
Returns a newLayout.ForFlowLayoutwith theFlowCellat the given child index replaced by the supplied value. All other child constraints and all other properties are copied unchanged. The intended way of creatingFlowCells is through theUILayoutConstants.AUTO_SPAN(Configurator)factory method!
Because the underlying storage is a sparse
Association, no padding is needed: the constraint is stored at exactlyindex, regardless of whether lower indices have entries.
Another important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any size specific span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
index- The zero-based index of the child whose constraint to update.childConstraint- The newFlowCellfor the child atindex.- Returns:
- A new
Layout.ForFlowLayoutwith the updated child constraint atindex. - Throws:
IndexOutOfBoundsException- ifindexis negative.
-
withChildConstraint
Returns a newLayout.ForFlowLayoutwith theFlowCellat the given child index replaced by one built from the suppliedConfiguratorlambda. The lambda receives aFlowCellConfand returns the configured version, matching exactly the API ofUILayoutConstants.AUTO_SPAN(Configurator):
The intended way of creatingLayout.flow() .withChildConstraint(0, it -> it.small(12).medium(6).large(4)) .withChildConstraint(1, it -> it.small(12).medium(6).large(8))FlowCells is through theUILayoutConstants.AUTO_SPAN(Configurator)factory method!
An important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any size specific span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
index- The zero-based index of the child whose constraint to update.cellConfig- AConfiguratorthat configures theFlowCellConffor the child's responsive span policy.- Returns:
- A new
Layout.ForFlowLayoutwith the updated child constraint atindex. - Throws:
IndexOutOfBoundsException- ifindexis negative.
-
withAddedChildConstraint
Returns a newLayout.ForFlowLayoutwith the suppliedFlowCellappended to the end of the existing child-constraint tuple. This is a convenient alternative towithChildConstraints(FlowCell...)when building up constraints one at a time:
The intended way of creatingimport static swingtree.UI.*; // ... Layout.flow() .withAddedChildConstraint( AUTO_SPAN(it -> it.small(12).medium(6)) ) .withAddedChildConstraint( AUTO_SPAN(it -> it.small(12).medium(6)) )FlowCells is through theUILayoutConstants.AUTO_SPAN(Configurator)factory method!
An important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any size specific span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
childConstraint- TheFlowCellto append as the next child constraint.- Returns:
- A new
Layout.ForFlowLayoutwith the constraint appended.
-
withAddedChildConstraint
Returns a newLayout.ForFlowLayoutwith aFlowCellbuilt from the suppliedConfiguratorlambda appended to the end of the existing child-constraint tuple. The lambda receives aFlowCellConfand returns the configured version, matching exactly the API ofUILayoutConstants.AUTO_SPAN(Configurator):
The intended way of creatingLayout.flow() .withAddedChildConstraint( it -> it.small(12).medium(6) ) .withAddedChildConstraint( it -> it.small(12).medium(6) )FlowCells is through theUILayoutConstants.AUTO_SPAN(Configurator)factory method!
An important edge case to consider when writing a responsive flow layout:
If aFlowCellis passed to the responsive flow layout without any size specific span policies defined, it will always default to spanning 12 cells at all parent size categories!- Parameters:
cellConfig- AConfiguratorthat configures theFlowCellConffor the appended child's responsive span policy.- Returns:
- A new
Layout.ForFlowLayoutwith the constraint appended.
-
hashCode
public int hashCode() -
equals
-
installFor
Installs aResponsiveGridFlowLayoutonto the supplied component and applies all constraints stored in this configuration.The installation proceeds in two phases:
- Layout manager — if no
ResponsiveGridFlowLayoutis currently installed, a new one is created with the stored alignment and gap settings. If one is already installed, only the properties that have changed are updated in-place andJComponent.revalidate()is called. - Child constraints — if the child-constraint tuple is non-empty,
each stored
FlowCellis written as aAddConstraintclient property onto the corresponding direct child (using the same key thatResponsiveGridFlowLayout.addLayoutComponent(java.lang.String, java.awt.Component)uses, so the layout manager picks them up on the next layout pass). Only entries that differ from the currently stored value are written, andJComponent.revalidate()is called exactly once at the end if anything changed.
- Specified by:
installForin interfaceLayout- Parameters:
component- The component to install theResponsiveGridFlowLayoutfor.
- Layout manager — if no
-
toString
-