Class Container<W extends Container<W>>

java.lang.Object
limn.scene.Widget<W>
limn.scene.layout.Container<W>
Direct Known Subclasses:
Flex, Grid, Stack, Wrap

public abstract class Container<W extends Container<W>> extends Widget<W>
A widget whose children are whatever the application puts in it: the one kind of widget that adds and removes children in public.

Every other widget arranges children of its own — a table its rows, a tab pane its headers, a button its label — and adding to one of those from outside either did nothing it would show or took a row out from under the widget's own bookkeeping. So Widget.add(limn.scene.Widget<?>) and Widget.remove(limn.scene.Widget<?>) are protected, and this class is where they become public. Column, Row, Wrap, Grid and Stack are containers; a layout an application writes extends this.

A container declares how far its children may paint past it, which is what partial rendering needs to know to repaint a focus ring at its edge; see paintOverflow(float). A layout that extends this inherits the declaration and the setter with it.

  • Constructor Details

    • Container

      public Container()
  • Method Details

    • add

      public void add(Widget<?> child)
      Appends a child (UI thread only).
      Overrides:
      add in class Widget<W extends Container<W>>
      Parameters:
      child - the child to append; never null
      Throws:
      IllegalArgumentException - if child already has a parent, or is an ancestor of this container, a scene's root, or an overlay on a scene's stack, which belongs to that scene until it is taken off the stack, the scene is given another root, or its window closes
    • add

      public void add(int index, Widget<?> child)
      Inserts a child at a position in Widget.children() (UI thread only).
      Overrides:
      add in class Widget<W extends Container<W>>
      Parameters:
      index - where the child goes, in [0, children().size()]
      child - the child to insert; never null
      Throws:
      IndexOutOfBoundsException - if index is outside that range
      IllegalArgumentException - if child already has a parent, or is an ancestor of this container, a scene's root, or an overlay on a scene's stack, as add(Widget) says
    • remove

      public void remove(Widget<?> child)
      Removes a child (UI thread only); a widget that is not a child is ignored.
      Overrides:
      remove in class Widget<W extends Container<W>>
    • paintOverflow

      public W paintOverflow(float points)
      Declares how far this container's children may paint past its box, in logical points, in place of the reach the theme gives every layout. UI thread only.

      What it is for. A layout that does not clip lets what its children draw outside themselves show outside it too: a focus ring on a control at the edge of a row hangs past the row. Partial rendering repaints only what changed, and a repaint pass skips any subtree whose box, grown by what the subtree's root declares it paints outside itself, misses the pass. So a pass landing only in the band just outside a layout that declared too little (a neighbour's hover, a caret beside it) skipped the layout, never painted the control, and wiped the ring's ink in that band.

      By default a container declares the reach of the focus ring in the theme in effect for it, Theme.focusRingReach(), which covers the ring of every control the toolkit ships. Declare more when a child paints farther (a colour plane's cursor centred on its edge, a glow, a badge placed across the corner), and less, down to 0, when the children are known to stay inside, which spares the band on every repaint of this container. paintOverflowFromTheme() goes back to the theme's number.

      It is what paintOutset() answers, the protected hook partial rendering reads, and this is its public setter. So it grows this container's damage too: an invalidate() repaints the box and the band. A container that clips its children declares nothing by default, because its clip already bounds them, and a number set here still counts. A subclass that overrides paintOutset() for painting of its own answers the larger of that and super.paintOutset(), or this setter no longer reaches it.

      The number is one per container and is not added up from the children: a child that paints farther than its layouts declare still loses the part beyond. That is the price of asking it in O(1), since a repaint pass asks it of every layout it considers.

      A declaration already in force changes nothing and repaints nothing. A new one repaints this container and the band it now declares, so that whatever a child draws there is drawn at once rather than at the next pass that reaches it.

      Parameters:
      points - how far the children may paint past each side of this box, in logical points
      Returns:
      this container
      Throws:
      IllegalArgumentException - when negative, NaN or infinite
    • paintOverflowFromTheme

      public W paintOverflowFromTheme()
      Goes back to declaring the reach of the theme's focus ring for the children, which is the default; see paintOverflow(float). Repaints nothing when that is already the declaration. UI thread only.
      Returns:
      this container
    • paintOutset

      protected float paintOutset()
      What paintOverflow(float) declared; else nothing when this container clips its children, whose clip bounds them; else the reach of the focus ring in the theme in effect for it. O(1) and allocation-free: no child is visited.
      Overrides:
      paintOutset in class Widget<W extends Container<W>>