Fork us on GitHub

Button Lists

Easier lists of checkboxes, radio buttons etc.
Button Lists

Button Lists

I wrote in the past about the problems in the List class, so I won’t rehash them here. However, the ideas behind list are still valuable. One such idea is the list model which allows us to separate the state from the view. Unfortunately the renderer architecture makes this hard to implement for most developers and limits the flexibility of the API.

To leverage this idea with the easier to use layout/container hierarchy we introduced ButtonList and its subclasses: CheckBoxList, RadioButtonList & SwitchList.

We also added a new MultipleSelectionListModel which extends the ListModel with multi-selection capabilities. This allows us to use a set of buttons as we would use a list and also generate them from data more easily.

In the code below we show two lists that use the same model. Changes to the checkboxes reflect instantly in the switch and vice versa:

Form hi = new Form("Button Lists", new BorderLayout());
SwitchList switchList = new SwitchList(new DefaultListModel("Red", "Green", "Blue", "Indigo"));
switchList.addActionListener(e->{
    Log.p("Selected indices: "+Arrays.toString(switchList.getMultiListModel().getSelectedIndices()));
}); (1)
switchList.setScrollableY(true);
Button clearSelections = new Button("Clear");
clearSelections.addActionListener(e ->
    switchList.getMultiListModel().setSelectedIndices());

Button addOption = new Button("Add Option");
addOption.addActionListener(e -> { (2)
    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->{ (3)
    boolean yScroll = true;
    switch (layoutSelector.getModel().getSelectedIndex()) {
        case 0:
            switchList.setLayout(new FlowLayout());
            break;
        case 1:
            switchList.setLayout(BoxLayout.x());
            yScroll = false;
            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.setScrollableX(!yScroll);
    switchList.setScrollableY(yScroll);
    switchList.animateLayout(300);
});
CheckBoxList checkBoxList = new CheckBoxList(switchList.getMultiListModel()); (4)
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();
1 Instead of binding multiple listeners we can bind a listener to the list itself and get the selections
2 It’s easy to add options like clear selection and add option thanks to the structure of the list model
3 This list uses a layout as it’s in-effect just a Container
4 The CheckBoxList uses the same model as the SwitchList
Demo of the button list
Figure 1. Demo of the button list classes
Share this Post:

Posted by Shai Almog

Shai is the co-founder of Codename One. He's been a professional programmer for over 25 years. During that time he has worked with dozens of companies including Sun Microsystems.
For more follow Shai on Twitter & github.