Package swingtree.api

Class Layout.None

java.lang.Object
swingtree.api.Layout.None
All Implemented Interfaces:
Layout
Enclosing interface:
Layout

@Immutable public static final class Layout.None extends Object implements Layout
The Layout.None layout removes any existing LayoutManager from a component (sets it to null), enabling fully manual positioning of child components via Component.setBounds(int, int, int, int).

Beyond simply clearing the layout manager, a Layout.None instance can carry a sparse Association of per-child Bounds that are applied to the component's direct children during installFor(JComponent). This lets you declare the absolute position and size of each child you care about right inside the Layout object, keeping the layout specification co-located with the component tree rather than scattered across imperative setup code:


      import static swingtree.UI.*;
      import swingtree.layout.Bounds;
      // ...
      Var<Layout> layout = Var.of(
          Layout.none(
              Bounds.of(  0,   0, 120, 40),  // child 0
              Bounds.of(130,   0, 120, 40),  // child 1
              Bounds.of(  0,  50, 250, 80)   // child 2
          )
      );

      UI.panel().withLayout(layout)
        .add( button("A") )
        .add( button("B") )
        .add( label("C")  );
  
Because the association is sparse you can also target a single child by index without touching the others:

      layout.set( Layout.none().withChildBound(2, Bounds.of(0, 50, 250, 80)) );
  

Note that this is different from the Layout.Unspecific layout, which does nothing at all — Layout.None actively removes the layout manager.

  • Method Details

    • withChildBounds

      public Layout.None withChildBounds(sprouts.Association<Integer,Bounds> childBounds)
      Returns a new Layout.None layout whose per-child Bounds are replaced by the supplied sorted Association.

      Keys are child indices (0 = first child, 1 = second, etc.); the association is sparse, so you only need to include entries for the children you actually want to position. Children whose index has no entry are left untouched. An empty association produces the plain "remove layout only" behaviour.

      Parameters:
      childBounds - A sorted Association mapping child indices to the Bounds to apply.
      Returns:
      A new Layout.None layout with the updated child bounds, or the shared Layout.none() constant when the association is empty.
    • withChildBounds

      public Layout.None withChildBounds(Bounds... childBounds)
      Returns a new Layout.None layout with per-child Bounds built from the supplied varargs array. Entries are mapped positionally: index 0 applies to the first child, index 1 to the second, and so on. Passing an empty array returns the shared Layout.none() constant.
      Parameters:
      childBounds - The Bounds to apply to the component's children, in child-index order.
      Returns:
      A new Layout.None layout with the updated child bounds.
    • withChildBound

      public Layout.None withChildBound(int index, Bounds childBound)
      Returns a new Layout.None layout with the Bounds at the given child index replaced by the supplied value. All other child bounds are copied unchanged.

      Because the underlying storage is a sparse Association, no padding is needed: the bound is stored at exactly index, regardless of whether lower indices have entries.

      Parameters:
      index - The zero-based index of the child whose bounds to update.
      childBound - The new Bounds for the child at index.
      Returns:
      A new Layout.None layout with the updated child bound at index.
      Throws:
      IndexOutOfBoundsException - if index is negative.
    • withAddedChildBound

      public Layout.None withAddedChildBound(Bounds childBound)
      Returns a new Layout.None layout with the supplied Bounds appended as the constraint for the next child in sequence (i.e. at index = max existing key + 1, or 0 if no bounds have been set yet).
      Parameters:
      childBound - The Bounds to append for the next child.
      Returns:
      A new Layout.None layout with the bound appended.
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface Layout
      Overrides:
      hashCode in class Object
      Returns:
      A hash code value for this layout.
    • equals

      public boolean equals(Object o)
      Specified by:
      equals in interface Layout
      Overrides:
      equals in class Object
      Parameters:
      o - The object to compare this layout to.
      Returns:
      true if the supplied object is a layout that is equal to this layout, false otherwise.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • installFor

      public void installFor(JComponent component)
      Installs this layout for the supplied component in two phases:
      1. Layout removal — the existing LayoutManager (if any) is replaced with null, enabling absolute positioning of child components.
      2. Child bounds — if any per-child Bounds were specified, each stored entry is applied to the corresponding direct child of component (by index) via Component.setBounds(int, int, int, int). Only entries that differ from the child's current bounds are written, and Component.repaint() is called exactly once at the end if anything changed.
      Specified by:
      installFor in interface Layout
      Parameters:
      component - The component to remove the layout manager from and optionally apply child bounds to.