Skip to content

From the Ground Up 02: CheckBoxes, Radio Buttons, and ButtonGroups

raeleus edited this page Jul 30, 2023 · 4 revisions

CheckBox actually inherits from TextButton, so you can apply the techniques from the previous tutorial to these widgets. In fact, CheckBox behaves almost exactly like ImageTextButton, making the class redundant. Nevertheless, some checkbox techniques can be learned in this space.

CheckboxStyle

Unselected checkboxes usually have an empty square followed by text. "checkboxOff" is the drawable for the empty box. Notice that you have to add some white space to the right of the image to ensure that the text is not pressed up against the graphic.
checkbox

"font" is the font you wish to use for the text. As with TextButton, you can color the font based on the state with "fontColor", "downFontColor", and the like.

When the checkbox is selected, it usually has a tick mark in it. This can be a check mark, an "x", a square, or whatever fits your fancy. Set this Drawable as your "checkboxOn" value.
checkbox-checked

Similarly, set the "checkboxOver", "checkboxOnOver", "checkboxOffDisabled", and "checkboxOnDisabled" fields to their corresponding values.
checkbox-pressed checkbox-checked-pressed checkbox-pressed checkbox-checked-pressed

Radio Buttons

Radio buttons are merely checkboxes with circular images instead of square ones. Some UI toolkits want to make a distinction between the two, but there doesn't have to be. I believe the call for a RadioButton class is a pointless one.
radio radio-checked radio-pressed radio-checked-pressed

Button Groups

But how do you get the behavior of a radio button if you don't have a RadioButton class? Usually you can only select one radio in a group of radio buttons. The simple answer is the ButtonGroup. ButtonGroup can collect any assortment of buttons and apply rules to them. All CheckBoxes are TextButtons, so they qualify.

ButtonGroup<CheckBox> buttonGroup = new ButtonGroup<>();

CheckBox checkBox = new CheckBox("Choice 1", skin, "radio");
root.add(checkBox);
buttonGroup.add(checkBox);

root.row();
checkBox = new CheckBox("Choice 2", skin, "radio");
root.add(checkBox);
buttonGroup.add(checkBox);

root.row();
checkBox = new CheckBox("Choice 3", skin, "radio");
root.add(checkBox);
buttonGroup.add(checkBox);

If you want to be able to select more than one item at a time, see ButtonGroup#setMinCheckCount() and ButtonGroup#setMaxCheckCount().

buttonGroup.setMinCheckCount(1);
buttonGroup.setMaxCheckCount(2);

If you exceed the max check count, the last checkbox to be selected will be unselected. You can change this behavior with ButtonGroup#setUncheckLast()

buttonGroup.setUncheckLast(true);

You can add ChangeListeners to each of your checkboxes like a Button. An alternative is overriding the ButtonGroup#canCheck() method.

ButtonGroup<CheckBox> buttonGroup = new ButtonGroup<CheckBox>() {
    @Override
    protected boolean canCheck(CheckBox checkBox, boolean newState) {
        boolean returnValue = super.canCheck(checkBox, newState);
        
        switch (getCheckedIndex()) {
            case 0:
                System.out.println("The first checkbox was checked.");
                break;
            case 1:
                System.out.println("The second checkbox was checked.");
                break;
        }
        
        return returnValue;
    }
};

The reason you'll want to override canCheck() is that you can return false if you don't want a checkbox to be checked based on your own criteria.

CheckBox wearHatcheckBox = new CheckBox("Wear hat", skin);
root.add(wearHatcheckBox);
boolean hasHat = false;
ButtonGroup<CheckBox> buttonGroup = new ButtonGroup<CheckBox>() {
    @Override
    protected boolean canCheck(CheckBox checkBox, boolean newState) {
        boolean returnValue = super.canCheck(checkBox, newState);
        
        if (!hasHat && checkBox == wearHatcheckBox) return false;
        
        return returnValue;
    }
};
buttonGroup.add(wearHatcheckBox);

ButtonGroup can be applied to any kind of Button, not just CheckBox.

ButtonGroup<TextButton> buttonGroup = new ButtonGroup<TextButton>();

Further Steps

A major component to the interactive UI widgets you've learned is text, but what if you only wanted to display some basic information? Continue with 03 Labels and TextTooltips or return to the table of contents.

Clone this wiki locally