Class ButtonGroup

java.lang.Object
vaadinx.swing.ButtonGroup
All Implemented Interfaces:
Serializable

public class ButtonGroup extends Object implements Serializable
Emulator port of ButtonGroup, accepting AbstractButton subclasses (the JDK class accepts javax.swing.AbstractButton, which our ported subclasses do not extend). Per D_buttongroup, coordination operates on the ported buttons directly; ButtonModel-taking JDK methods are preserved in shape so import-swap compiles, but drop-and-WARN at runtime (R_match_swing_errors sub-bucket (c) — AbstractButton stores selection directly, so there is no model to return; migrators iterate via getElements() + button.isSelected()).

Coordination mirrors JDK DefaultButtonModel.setSelected: a selection-bearing subclass (JToggleButton, JCheckBoxMenuItem, JRadioButtonMenuItem) consults its installed group at the top of setSelected / makeOnClick via the package-private setSelectedButton(AbstractButton, boolean) / isSelectedButton(AbstractButton) hooks. The group flips its selection slot and cascades setSelected(false) to the previously-selected sibling; a deselect request on the current selection is a no-op (JDK's suppression of click-to-deselect a radio). Browser-click coordination on JToggleButton-in-group rides the SJToggleButton→emulator bridge per D_buttongroup_browser_click.

See Also:
  • Field Details

    • buttons

      protected final Vector<AbstractButton> buttons
      Buttons in the group, in insertion order. Matches JDK's protected Vector<AbstractButton> field by element class — only ours holds AbstractButton, not AbstractButton. Made package-private so tests can introspect; JDK exposes it as protected, which we don't need since this class is non-final but doesn't have a paired UI / impl subclass that mutates the list directly.
  • Constructor Details

    • ButtonGroup

      public ButtonGroup()
      Default constructor — empty group, no selection.
  • Method Details

    • add

      public void add(AbstractButton b)
      Add a button to the group. JDK contract: a null argument is a silent no-op (real Swing's body short-circuits on null without NPE). If the button is already selected when added, it becomes the group's selection — unless another button is already selected, in which case the newly-added button is forced deselected to maintain the at-most-one invariant.
    • remove

      public void remove(AbstractButton b)
      Remove a button from the group. JDK contract: a null argument is a silent no-op. If the removed button was the selection, the group's selection clears.
    • clearSelection

      public void clearSelection()
      Clear the current selection. The previously-selected button (if any) is told to deselect via its own setSelected(false) — which fires Item + Change events, just as a JDK radio's deselection would. The group's selection slot clears before the cascade so the outgoing button's own setSelected re-consult of the group sees a null selection (avoiding the JDK-no-op-on-false branch from interfering).
    • getElements

      public Enumeration<AbstractButton> getElements()
      Enumerate the buttons in insertion order. Returns Enumeration<AbstractButton> where AbstractButton is AbstractButton — JDK's signature is Enumeration<javax.swing.AbstractButton>, an irreducible cross-package divergence (D_buttongroup_cross_package). Migrators iterating with a for (vaadinx.swing.AbstractButton b : Collections.list(group.getElements())) loop work without changes; cross-cast attempts to JDK AbstractButton would fail, but that pattern doesn't survive an import-swap anyway.
    • getButtonCount

      public int getButtonCount()
      Number of buttons in the group.
    • getSelection

      public ButtonModel getSelection()
      JDK contract: returns the selected button's ButtonModel. :emulators doesn't model ButtonModel, so this returns null with a WARN per R_match_swing_errors sub-bucket (c). Migrators relying on group.getSelection() chained dereferences (e.g. group.getSelection().isSelected()) will NPE — documented gap; use getElements() + per-button isSelected() instead.
    • isSelected

      public boolean isSelected(ButtonModel m)
      JDK contract: true if the given model is the group's selection. Drop-and-WARN — :emulators doesn't model ButtonModel, so the argument has no canonical match against our selectedButton slot. Always returns false. Use AbstractButton.isSelected() directly. R_match_swing_errors sub-bucket (c).
    • setSelected

      public void setSelected(ButtonModel m, boolean b)
      JDK contract: when b is true and m is not the current selection, set it as the new selection (deselecting the old one). Drop-and-WARN — :emulators doesn't model ButtonModel. Use the package-private setSelectedButton(AbstractButton, boolean) coordination hook from inside the ported AbstractButton subclasses instead. R_match_swing_errors sub-bucket (c).