Class ButtonGroup

java.lang.Object
limn.components.ButtonGroup

public final class ButtonGroup extends Object
Coordinates a set of RadioButtons so that exactly one is selected at a time. Selecting a member deselects the previous one (each radio's own onChange fires for both the leaving and the entering member) and fires the group's onSelect with the new index.

A group is one tab stop, not one per radio. Only the selected member (or the first enabled one, before anything is selected) can take focus, and the arrow keys move the selection and the focus together, wrapping at the ends and stepping over disabled members. That is the Windows and GTK convention, it is what macOS Full Keyboard Access does inside a group, and it is the pattern TabbedPane already uses for its headers. Without it a settings form of six groups of four options costs twenty-four tab stops instead of six.

  • Constructor Details

    • ButtonGroup

      public ButtonGroup()
  • Method Details

    • add

      public ButtonGroup add(RadioButton radio)
      Adds a radio to the group. If it is already selected, it becomes the group's selection.
    • onSelect

      public ButtonGroup onSelect(Consumer<Integer> listener)
      Called with the index of the newly selected radio, or with -1 when clearSelection() empties the group. A click, an arrow key and a setSelectedIndex(int) from code all arrive here.
    • selectedIndex

      public int selectedIndex()
      Returns:
      the index of the selected radio, or -1 when none. A group is one of the two widgets in this set that genuinely has no-selection as a state: it starts there, and clearSelection() goes back
    • selected

      public RadioButton selected()
      Returns:
      the selected radio, or null when none.
    • members

      public List<RadioButton> members()
      Returns:
      an immutable view of the members, in the order they were added
    • setSelectedIndex

      public ButtonGroup setSelectedIndex(int index)
      Selects the member at index and fires onSelect; code, a click and an arrow key take the same path, so a listener sees every change either way. Selecting the member that is already selected changes nothing and fires nothing; that early return is what keeps two controls bound to each other from recursing, so do not remove it. UI thread only.
      Parameters:
      index - a member in [0, memberCount), in the order they were added
      Throws:
      IndexOutOfBoundsException - if index is not a member; a group with no members has none, so every index throws there. -1 is not the way to empty the group; clearSelection() is.
    • clearSelection

      public ButtonGroup clearSelection()
      Puts the group back in the state it had before anything was selected: selectedIndex() reports -1, the leaving member's own onChange fires with false, and onSelect fires with -1. No-op when nothing is selected. UI thread only.

      A radio group is one choice out of many and offers no way to un-choose from the keyboard or the mouse: this is the reset a form needs, and the only route back.