# Class ButtonList

java.lang.Object
com.codename1.ui.Component
com.codename1.ui.Container
com.codename1.components.ButtonList

All Implemented Interfaces:
  `Animation, Editable, ActionListener, ActionSource, DataChangedListener, SelectionListener, StyleListener, Iterable<Component>`

Direct Known Subclasses:
  `CheckBoxList, RadioButtonList, SwitchList`

public abstract class ButtonList extends Container implements DataChangedListener, SelectionListener, ActionListener, ActionSource

An abstract base class for a list of buttons. Most useful for grids of toggle widgets such as Radio Buttons, CheckBoxes, and Switches. There are concrete implementations for `Switch` (`SwitchList`), `RadioButton` (`RadioButtonList`, and `CheckBox` (`CheckBoxList`).

This abstraction allows you to work with a set of toggle buttons as a single unit. It uses a `ListModel` to store the toggle options, and will automatically stay in sync with its model when options are added or removed, or the selection is changed.

    package com.codename1.testproj;

    import com.codename1.components.CheckBoxList;
    import com.codename1.components.RadioButtonList;
    import com.codename1.components.SwitchList;
    import static com.codename1.ui.CN.*;
    import com.codename1.io.Log;
    import com.codename1.ui.Button;
    import com.codename1.ui.Form;
    import com.codename1.ui.Dialog;
    import com.codename1.ui.layouts.BorderLayout;
    import com.codename1.ui.layouts.BoxLayout;
    import com.codename1.ui.layouts.FlowLayout;
    import com.codename1.ui.plaf.UIManager;
    import com.codename1.ui.util.Resources;
    import com.codename1.ui.Toolbar;
    import com.codename1.ui.Command;
    import com.codename1.ui.TextField;
    import com.codename1.ui.layouts.GridLayout;
    import com.codename1.ui.list.DefaultListModel;
    import com.codename1.ui.table.TableLayout;
    import java.util.Arrays;

    /**
     * This file was generated by [Codename One](https://www.codenameone.com/) for the purpose
     * of building native mobile applications using Java.
     */
    public class TestProject {

        private Form current;
        private Resources theme;

        public void init(Object context) {
            // use two network threads instead of one
            updateNetworkThreadCount(2);

            theme = UIManager.initFirstTheme("/theme");

            // Enable Toolbar on all Forms by default
            Toolbar.setGlobalToolbar(true);

            // Pro only feature
            Log.bindCrashProtection(true);

            addNetworkErrorListener(err -> {
                // prevent the event from propagating
                err.consume();
                if(err.getError() != null) {
                    Log.e(err.getError());
                }
                Log.sendLogAsync();
                Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
            });
        }

        public void start() {
            if(current != null){
                current.show();
                return;
            }

            testButtonLists();
        }

        public void testButtonLists() {
            Form hi = new Form("Hi", new BorderLayout());

            SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
            switchList.addActionListener(e->{
                Log.p("Action event received from "+e.getSource());
                Log.p("Selected indices: "+Arrays.toString(switchList.getMultiListModel().getSelectedIndices()));
            });

            Button clearSelections = new Button("Clear");
            clearSelections.addActionListener(e -> {
                switchList.getMultiListModel().setSelectedIndices();
            });

            Button addOption = new Button("Add Option");
            addOption.addActionListener(e -> {
                callSerially(()->{
                    TextField val = new TextField();
                    Command res = Dialog.show("Enter label", val, new Command("OK"));
                    switchList.getMultiListModel().addItem(val.getText());

                });
            });

            RadioButtonList layoutSelector = new RadioButtonList(new DefaultListModel("Flow", "X", "Y", "2-Col Table", "3-Col Table", "2 Col Grid", "3 Col Grid"));
            layoutSelector.addActionListener(e->{
                switch (layoutSelector.getModel().getSelectedIndex()) {
                    case 0: switchList.setLayout(new FlowLayout());
                    break;
                    case 1: switchList.setLayout(BoxLayout.x());
                    break;
                    case 2: switchList.setLayout(BoxLayout.y());
                    break;
                    case 3: switchList.setLayout(new TableLayout(switchList.getComponentCount()/2+1, 2));
                    break;
                    case 4: switchList.setLayout(new TableLayout(switchList.getComponentCount()/3+1, 3));
                    break;
                    case 5: switchList.setLayout(new GridLayout(2));
                    break;
                    case 6: switchList.setLayout(new GridLayout(3));
                }
                switchList.animateLayout(300);
            });

            CheckBoxList checkBoxList = new CheckBoxList(switchList.getMultiListModel());
            checkBoxList.addActionListener(e-> {
                System.out.println("CheckBox actionEvent.  "+Arrays.toString(checkBoxList.getMultiListModel().getSelectedIndices()));
            });
            hi.add(BorderLayout.NORTH, layoutSelector);
            hi.add(BorderLayout.CENTER, BoxLayout.encloseY(checkBoxList, switchList));
            hi.add(BorderLayout.SOUTH, GridLayout.encloseIn(2, addOption, clearSelections));
            hi.show();

        }

        public void stop() {
            current = getCurrentForm();
            if(current instanceof Dialog) {
                ((Dialog)current).dispose();
                current = getCurrentForm();
            }
        }

        public void destroy() {
        }

    }

Examples

Switch List in a FlowLayout:

    `SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
    switchList.setLayout(new FlowLayout());`

Switch List in a BoxLayout.Y:

    `SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
    switchList.setLayout(BoxLayout.y());`

Switch List in a Grid Layout:

Switch List in a Table Layout:

2 Columns:

    `SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
    switchList.setLayout(new TableLayout(switchList.getComponentCount()/2+1, 2));`

3 Columns:

    `SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
    switchList.setLayout(new TableLayout(switchList.getComponentCount()/3+1, 3));`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static interface`
  `ButtonList.Decorator<M, V extends Component>`
  An interface that can be implemented to provide custom decoration/undecoration of the buttons as they are created/removed.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected boolean`
  `ready`

  ### Fields inherited from class Component

  `BASELINE, BOTTOM, BRB_CENTER_OFFSET, BRB_CONSTANT_ASCENT, BRB_CONSTANT_DESCENT, BRB_OTHER, CENTER, CROSSHAIR_CURSOR, DEFAULT_CURSOR, DRAG_REGION_IMMEDIATELY_DRAG_X, DRAG_REGION_IMMEDIATELY_DRAG_XY, DRAG_REGION_IMMEDIATELY_DRAG_Y, DRAG_REGION_LIKELY_DRAG_X, DRAG_REGION_LIKELY_DRAG_XY, DRAG_REGION_LIKELY_DRAG_Y, DRAG_REGION_NOT_DRAGGABLE, DRAG_REGION_POSSIBLE_DRAG_X, DRAG_REGION_POSSIBLE_DRAG_XY, DRAG_REGION_POSSIBLE_DRAG_Y, E_RESIZE_CURSOR, HAND_CURSOR, LEFT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NW_RESIZE_CURSOR, RIGHT, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, TOP, W_RESIZE_CURSOR, WAIT_CURSOR`

  ### Fields inherited from interface DataChangedListener

  `ADDED, CHANGED, REMOVED`

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `ButtonList(ListModel model, boolean allowMultipleSelection)`
  Creates a new ButtonList.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `actionPerformed(ActionEvent evt)`
  Invoked when an action occurred on a component
  `void`
  `addActionListener(ActionListener l)`
  Add a listener to be notified when any of the buttons in the list are pressed.
  `void`
  `addDecorator(ButtonList.Decorator decorator)`
  Adds a decorator that can be used to customize a button when it is created
  `protected abstract Component`
  `createButton(Object model)`
  Creates a new button for this list.
  `void`
  `dataChanged(int status, int index)`
  Invoked when there was a change in the underlying model
  `protected Component`
  `decorateComponent(Object modelItem, Component b)`
  Decorates buttons.
  `protected final void`
  `fireReady()`
  This should be called by the concrete implementation once it is ready to generate the buttons.
  `ListModel`
  `getModel()`
  Returns the model.
  `MultipleSelectionListModel`
  `getMultiListModel()`
  For multi-selection models (e.g. for checkbox or switch lists), this will return the model as a `MultiSelectionListModel`.
  `protected void`
  `onReady(Runnable r)`
  Wrap any calls that requires that the infrastructure is ready inside this.
  `void`
  `refresh()`
  Refreshes the container - regenerating all of the buttons in the list from the model.
  `void`
  `removeActionListener(ActionListener l)`
  Remove a listener so that it no longer is notified when buttons in the list are pressed.
  `void`
  `removeDecorator(ButtonList.Decorator decorator)`
  Removes a decorator.
  `void`
  `selectionChanged(int oldSelected, int newSelected)`
  Indicates the selection changed in the underlying list model
  `void`
  `setCellUIID(String uiid)`
  Sets the UIID for cells of the list.
  `void`
  `setLayout(Layout layout)`
  Sets the layout for the list.
  `final void`
  `setModel(ListModel model)`
  `protected abstract void`
  `setSelected(Component button, boolean selected)`
  Sets the given button's selected state.
  `protected Component`
  `undecorateComponent(Component b)`
  Undecorates buttons.

  ### Methods inherited from class Container

  `add, add, add, add, add, add, addAll, addComponent, addComponent, addComponent, addComponent, animateHierarchy, animateHierarchyAndWait, animateHierarchyFade, animateHierarchyFadeAndWait, animateLayout, animateLayoutAndWait, animateLayoutFade, animateLayoutFadeAndWait, animateUnlayout, animateUnlayoutAndWait, applyRTL, calcPreferredSize, cancelRepaints, clearClientProperties, constrainHeightWhenScrollable, constrainWidthWhenScrollable, contains, createAnimateHierarchy, createAnimateHierarchyFade, createAnimateLayout, createAnimateLayoutFade, createAnimateLayoutFadeAndWait, createAnimateMotion, createAnimateUnlayout, createReplaceTransition, dragInitiated, drop, encloseIn, encloseIn, findDropTargetAt, findFirstFocusable, fireClicked, flushReplace, forceRevalidate, getBottomGap, getChildrenAsList, getClosestComponentTo, getComponentAt, getComponentAt, getComponentCount, getComponentIndex, getGridPosX, getGridPosY, getLayout, getLayoutHeight, getLayoutWidth, getLeadComponent, getLeadParent, getResponderAt, getSafeAreaRoot, getScrollIncrement, getSideGap, getUIManager, initLaf, invalidate, isEnabled, isSafeArea, isSafeAreaRoot, isScrollableX, isScrollableY, isSelectableInteraction, isSurface, iterator, iterator, keyPressed, keyReleased, layoutContainer, morph, morphAndWait, paint, paintComponentBackground, paintGlass, paramString, pointerPressed, refreshTheme, removeAll, removeComponent, replace, replace, replaceAndWait, replaceAndWait, replaceAndWait, revalidate, revalidateLater, revalidateWithAnimationSafety, scrollComponentToVisible, setCellRenderer, setEnabled, setLeadComponent, setSafeArea, setSafeAreaRoot, setScrollable, setScrollableX, setScrollableY, setScrollIncrement, setShouldCalcPreferredSize, setShouldLayout, setUIManager, updateTabIndices`

  ### Methods inherited from class Component

  `accessibilityChanged, accessibilityChanged, addContextMenuListener, addDragFinishedListener, addDragOverListener, addDropListener, addFocusListener, addLongPressListener, addMouseWheelListener, addPointerDraggedListener, addPointerPressedListener, addPointerReleasedListener, addPullToRefresh, addScrollListener, addStateChangeListener, addStylusListener, animate, announceForAccessibility, bindProperty, blocksSideSwipe, calcScrollSize, consumesRawTextInput, contains, containsOrOwns, createStyleAnimation, deinitialize, deinitializeCustomStyle, deregisterFromAnimation, dragEnter, dragExit, dragFinished, draggingOver, drawDraggedImage, focusGained, focusLost, getAbsoluteX, getAbsoluteY, getAccessibilityNode, getAccessibilityText, getAllStyles, getAnimationManager, getBaseline, getBaselineResizeBehavior, getBindablePropertyNames, getBindablePropertyTypes, getBorder, getBoundPropertyValue, getBounds, getBounds, getClientProperty, getCloudBoundProperty, getCloudDestinationProperty, getComponentForm, getComponentState, getCursor, getDefaultDragTransparency, getDirtyRegion, getDisabledStyle, getDraggedx, getDraggedy, getDragImage, getDragRegionStatus, getDragSpeed, getDragTransparency, getEditingDelegate, getHeight, getInlineAllStyles, getInlineDisabledStyles, getInlinePressedStyles, getInlineSelectedStyles, getInlineStylesTheme, getInlineUnselectedStyles, getInnerHeight, getInnerPreferredH, getInnerPreferredW, getInnerWidth, getInnerX, getInnerY, getLabelForComponent, getName, getNativeOverlay, getNextFocusDown, getNextFocusLeft, getNextFocusRight, getNextFocusUp, getOuterHeight, getOuterPreferredH, getOuterPreferredW, getOuterWidth, getOuterX, getOuterY, getOwner, getParent, getPreferredH, getPreferredSize, getPreferredSizeStr, getPreferredTabIndex, getPreferredW, getPressedStyle, getPropertyNames, getPropertyTypeNames, getPropertyTypes, getPropertyValue, getSameHeight, getSameWidth, getScrollable, getScrollAnimationSpeed, getScrollDimension, getScrollOpacity, getScrollOpacityChangeSpeed, getScrollX, getScrollY, getSelectCommandText, getSelectedRect, getSelectedStyle, getSemantics, getStyle, getTabIndex, getTensileLength, getTextSelectionSupport, getTooltip, getTopLevelContainer, getUIID, getUnselectedStyle, getVisibleBounds, getVisibleBounds, getWidth, getX, getY, growShrink, handlesInput, hasFixedPreferredSize, hasFocus, hideNativeOverlay, initComponent, initCustomStyle, initDisabledStyle, initPressedStyle, initSelectedStyle, initUnselectedStyle, installDefaultPainter, isAlwaysTensile, isBlockLead, isCellRenderer, isChildOf, isDragActivated, isDragAndDropOperation, isDraggable, isDragRegion, isDropTarget, isEditable, isEditing, isFlatten, isFocusable, isGrabsPointerEvents, isHidden, isHidden, isHideInLandscape, isHideInPortrait, isHScrollThumbGrabbed, isHScrollThumbHover, isIgnorePointerEvents, isInClippingRegion, isInitialized, isOpaque, isOwnedBy, isPinchBlocksDragAndDrop, isRippleEffect, isRTL, isScrollable, isScrollVisible, isSetCursorSupported, isSmoothScrolling, isSnapToGrid, isStickyDrag, isTactileTouch, isTactileTouch, isTensileDragEnabled, isTraversable, isVisible, isVScrollThumbGrabbed, isVScrollThumbHover, keyRepeated, laidOut, longKeyPress, longPointerPress, onScrollX, onScrollY, onSetFocusable, paintBackground, paintBackgrounds, paintBorder, paintBorderBackground, paintComponent, paintComponent, paintIntersectingComponentsAbove, paintLock, paintLockRelease, paintRippleOverlay, paintScrollbars, paintScrollbarX, paintScrollbarY, paintShadows, parsePreferredSize, pinch, pinch, pinchReleased, pointerDragged, pointerDragged, pointerHover, pointerHoverPressed, pointerHoverReleased, pointerPressed, pointerReleased, pointerReleased, putClientProperty, refreshTheme, refreshTheme, registerForAnimation, remove, removeContextMenuListener, removeDragFinishedListener, removeDragOverListener, removeDropListener, removeFocusListener, removeLongPressListener, removeMouseWheelListener, removePointerDraggedListener, removePointerPressedListener, removePointerReleasedListener, removeScrollListener, removeStateChangeListener, removeStylusListener, repaint, repaint, requestFocus, resetFocusable, respondsToPointerEvents, rotation, scrollRectToVisible, scrollRectToVisible, setAccessibilityText, setAlwaysTensile, setBlockLead, setBoundPropertyValue, setCloudBoundProperty, setCloudDestinationProperty, setComponentState, setCursor, setDefaultDragTransparency, setDirtyRegion, setDisabledStyle, setDraggable, setDragTransparency, setDropTarget, setEditingDelegate, setFlatten, setFocus, setFocusable, setGrabsPointerEvents, setHandlesInput, setHeight, setHidden, setHidden, setHideInLandscape, setHideInPortrait, setHorizontalScrollBounds, setIgnorePointerEvents, setInitialized, setInlineAllStyles, setInlineDisabledStyles, setInlinePressedStyles, setInlineSelectedStyles, setInlineStylesTheme, setInlineUnselectedStyles, setIsScrollVisible, setLabelForComponent, setName, setNextFocusDown, setNextFocusLeft, setNextFocusRight, setNextFocusUp, setOpaque, setOwner, setPinchBlocksDragAndDrop, setPreferredH, setPreferredSize, setPreferredSizeStr, setPreferredTabIndex, setPreferredW, setPressedStyle, setPropertyValue, setPullToRefresh, setRippleEffect, setRTL, setSameHeight, setSameSize, setSameWidth, setScrollAnimationSpeed, setScrollOpacityChangeSpeed, setScrollSize, setScrollVisible, setScrollX, setScrollY, setSelectCommandText, setSelectedStyle, setSize, setSmoothScrolling, setSnapToGrid, setTabIndex, setTactileTouch, setTensileDragEnabled, setTensileLength, setTooltip, setTraversable, setUIID, setUIID, setUIIDFinal, setUnselectedStyle, setVerticalScrollBounds, setVisible, setWidth, setX, setY, shouldBlockSideSwipe, shouldBlockSideSwipeLeft, shouldBlockSideSwipeRight, shouldRenderComponentSelection, showNativeOverlay, startEditingAsync, stopEditing, stripMarginAndPadding, styleChanged, toImage, toString, unbindProperty, updateNativeOverlay, visibleBoundsContains`

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface Iterable

  `forEach`

- ## Field Details

  - ### ready

    protected boolean ready

- ## Constructor Details

  - ### ButtonList

    protected ButtonList(ListModel model, boolean allowMultipleSelection)

    Creates a new ButtonList.

    ###### Parameters

    - `model`: The options. Each will be represented by a button.

    - `allowMultipleSelection`: indicates that multiple selection is allowed or not

- ## Method Details

  - ### onReady

    protected void onReady(Runnable r)

    Wrap any calls that requires that the infrastructure is ready inside this.

    ###### Parameters

    - `r`: Will be run when buttons are ready to be generated.

  - ### fireReady

    protected final void fireReady()
    This should be called by the concrete implementation once it is ready to generate the buttons.

  - ### getMultiListModel

    public MultipleSelectionListModel getMultiListModel()

    For multi-selection models (e.g. for checkbox or switch lists), this will return the model as a `MultiSelectionListModel`. Otherwise it will return null.

    ###### Returns

    The model.

  - ### getModel

    public ListModel getModel()

    Returns the model.

    ###### Returns

    The model

  - ### setModel

    public final void setModel(ListModel model)

  - ### createButton

    protected abstract Component createButton(Object model)

    Creates a new button for this list. Should be implemented by subclasses to create the correct kind of button.

    ###### Parameters

    - `model`

  - ### setSelected

    protected abstract void setSelected(Component button, boolean selected)

    Sets the given button's selected state.

    ###### Parameters

    - `button`: The button (in the form produced by `#createButton`.

    - `selected`: Whether the button is selected or not.

  - ### setLayout

    public void setLayout(Layout layout)

    Sets the layout for the list. This refresh the list to match the new layout.

    ###### Parameters

    - `layout`: @param layout The layout to use. Only layouts that don't require constraints in `com.codename1.ui.Component)` may be used. E.g. `FlowLayout`, `BoxLyout`, `TableLayout`, `GridLayout` are all fine.
    Overrides:
      `setLayout` in class `Container`

  - ### refresh

    public void refresh()
    Refreshes the container - regenerating all of the buttons in the list from the model. This usually doesn't ever need to be called explicitly as it will be called automatically when the model changes, or the layout changes.

  - ### decorateComponent

    protected Component decorateComponent(Object modelItem, Component b)

    Decorates buttons. This allows subclasses to add event listeners to buttons.

    ###### Parameters

    - `b`: The button in the form returned by `#createButton(java.lang.Object)`

    ###### Returns

    Should pass back the same component it receives.

  - ### undecorateComponent

    protected Component undecorateComponent(Component b)

    Undecorates buttons. This allows subclasses to remove event listeners from buttons.

    ###### Parameters

    - `b`: The button in the form returned by `#createButton(java.lang.Object)`

    ###### Returns

    Should pass back the same component it receives.

  - ### dataChanged

    public void dataChanged(int status, int index)
    Description copied from interface: `DataChangedListener`

    Invoked when there was a change in the underlying model

    ###### Parameters

    - `type`: the type data change; REMOVED, ADDED or CHANGED

    - `index`: item index in a list model

    Specified by:
      `dataChanged` in interface `DataChangedListener`

  - ### selectionChanged

    public void selectionChanged(int oldSelected, int newSelected)
    Description copied from interface: `SelectionListener`

    Indicates the selection changed in the underlying list model

    ###### Parameters

    - `oldSelected`: old selected index in list model

    - `newSelected`: new selected index in list model

    Specified by:
      `selectionChanged` in interface `SelectionListener`

  - ### actionPerformed

    public void actionPerformed(ActionEvent evt)
    Description copied from interface: `ActionListener`

    Invoked when an action occurred on a component

    ###### Parameters

    - `evt`: @param evt event object describing the source of the action as well as its trigger
    Specified by:
      `actionPerformed` in interface `ActionListener`

  - ### addActionListener

    public void addActionListener(ActionListener l)

    Add a listener to be notified when any of the buttons in the list are pressed.

    ###### Parameters

    - `l`
    Specified by:
      `addActionListener` in interface `ActionSource`

  - ### removeActionListener

    public void removeActionListener(ActionListener l)

    Remove a listener so that it no longer is notified when buttons in the list are pressed.

    ###### Parameters

    - `l`
    Specified by:
      `removeActionListener` in interface `ActionSource`

  - ### setCellUIID

    public void setCellUIID(String uiid)

    Sets the UIID for cells of the list. Each cell will be a component as returned by the concrete implementation's `#createButton(java.lang.Object)` method.

    ###### Parameters

    - `uiid`

  - ### addDecorator

    public void addDecorator(ButtonList.Decorator decorator)

    Adds a decorator that can be used to customize a button when it is created

    ###### Parameters

    - `decorator`: A decorator.

  - ### removeDecorator

    public void removeDecorator(ButtonList.Decorator decorator)

    Removes a decorator.

    ###### Parameters

    - `decorator`