Binding of items in RadioButtonGroup

I am making a view that has many TextFields and ComboBoxes and CheckBoxes, where their values are handled by a single Binder. No problem there.

BUT: now I want to add 3 RadioButtons to the view, the values should come from the same Binder. Each RadioButton is bound to a different boolean field, only 1 of those fields can be true at the same time (perfect requirement for RadioBoxes).

Problem #1: There is no Component for a simple RadioButton (like there is for CheckBox), i can only find RadioButtonGroup. So i guess I will have to work with that one.

Problem #2: In the
Vaadin Docs
it specifically says:
“The advantages of the CheckBoxGroup component are that as it maintains the individual check box objects, you can get an array of the currently selected items easily, and that you can easily change the appearance of a single component and use it with a Binder.”

But I can’t find a way to bind the items of RadioButtonGroup, nor can I find any mention of it anywhere.

Is there a way to bind single Items in a RadioButtonGroup?

(If not, then I fear I will have to use CheckBoxes where RadioButtons would be a more logical approach.)

Here is some code to demonstrate what I am trying to accomplish:

// FooBar Class
private boolean foo = true;
private boolean bar = false;
private boolean fooBar = false;
// constructor, getters and setters


// My View
Binder<FooBar> binder = new Binder<>();
binder.setBean(new FooBar());

// this CheckBox works perfectly fine like this
Checkbox cb = new CheckBox();
cb.setCaption("Foo"); 
binder.forItem(cb).bind(f -> f.isFoo, (f, b) -> f.setFoo(b));

// this part is where I'm confused
RadioButtonGroup<String> rbg = new RadioButtonGroup<>();
rbg.setItems("Foo", "Bar", "FooBar");
// how can i bind each RadioButton to different fields of my FooBar Bean?
// because getItem() does not exist
binder.forItem(rbg.getItem(0)).bind(f -> f.isFoo, (f, b) -> f.setFoo(b));
binder.forItem(rbg.getItem(1)).bind(f -> f.isBar, (f, b) -> f.setBar(b));
binder.forItem(rbg.getItem(2)).bind(f -> f.isFooBar, (f, b) -> f.setFooBar(b));

Hi Kaspar,
the following is a quick and very, very, very dirty solution

    ....
    RadioButtonGroup<String> rbg = new RadioButtonGroup<>();
    rbg.setItems("Foo", "Bar", "FooBar");
    binder.forField(rbg).bind(RbgBinder::apply, RbgBinder::accept);
    ...
    private static class RbgBinder  {

        public static String apply(FooBar fooBar) {
            if (fooBar.isBar()) {
                return "Bar";
            } else if (fooBar.isFoo()) {
                return "Foo";
            } else if (fooBar.isFooBar()) {
                return "FooBar";
            }
            return null;
        }

        public static void accept(FooBar fooBar, String s) {
            fooBar.setFoo(false);
            fooBar.setBar(false);
            fooBar.setFooBar(true);
            switch (s) {
                case "Bar":
                    fooBar.setBar(true);
                    break;
                case "Foo":
                    fooBar.setFoo(true);
                    break;
                case "FooBar":
                    fooBar.setFooBar(true);
                    break;
            }
        }
    }

A better way could be to have getter/setter in FooBar class that accepts the string (or maybe an enum) and performes the logic (I think that when selection one option you will also set to false other bean values) instead of having external methods

Thanks Marco for the quickfix, but I was more looking for the ‘standard’ way to use RadioButtonGroup, hoping it would work in my situation (3 different fields).

I have also asked this exact question on StackOverflow where I got
an excellent answer
, which I want to share here too.


TL;DR from the answer:

RadioButtonGroups are typically used to assign value to a single attribute, an enum for example.


After I changed my 3 boolean fields to a single enum it worked like a charm.