Vaadin 8 - 如何绑定 RadioButtonGroup 的项目?

Vaadin 8 - How to bind items of RadioButtonGroup?

我正在创建一个包含许多 TextFields、ComboBox 和 CheckBox 的视图,它们的值由单个 Binder 处理。没问题。

但是:现在我想在视图中添加 3 个 RadioButton,这些值应该来自同一个 Binder。每个 RadioButton 都绑定到一个不同的布尔字段,这些字段中只有 1 个可以同时为真(对 RadioBoxes 的完美要求)。

问题 #1:简单的 RadioButton 没有组件(就像 CheckBox 一样),我只能找到 RadioButtonGroup。所以我想我将不得不与那个人一起工作。

问题 #2:在 Vaadin Docs 中它明确表示:

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.

但我找不到绑定 RadioButtonGroup 的项目的方法,也找不到任何提及它的地方。

有没有办法在 RadioButtonGroup 中绑定单个项目?
如果没有,那么我担心我将不得不使用复选框,而单选按钮是更合乎逻辑的方法。

下面是一些代码来演示我正在努力完成的事情:

// 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));

我建议考虑一些不同的方法。单选按钮通常用于将值分配给单个属性 - RadioButtonGroup 是单个表单字段 - 而不是分配给属性或字段列表,所以我想这就是你找不到直接解决方案的原因。

如果可能,将您的三个 boolean 更改为 enum,例如:

public enum RadioButtonValue {
   foo, bar, foobar;
}

这应该提供兼容的功能,因为您希望一次只限制三个布尔值中的一个为真。

然后class喜欢:

public class RadioButtonBean {
   @Getter @Setter // Lombok
   private RadioButtonValue radioButtonValue;
   // replaces boolean foo, bar, foobar;
}

让您轻松绑定:

RadioButtonGroup<RadioButtonValue> radioGroup = new RadioButtonGroup<>();
radioGroup.setCaption("Radiobutton group");
// populate with enum values as title or use setItemCaptionGenerator(...);
radioGroup.setDataProvider(
    new ListDataProvider<RadioButtonValue>( 
        Arrays.asList( RadioButtonValue.values() )
    )
);

final RadioButtonBean bean = new RadioButtonBean();
Binder<RadioButtonBean> binder = new Binder<>();
binder.setBean(bean);
binder.forField(radioGroup).bind(RadioButtonBean::getRadioButtonValue,
        RadioButtonBean::setRadioButtonValue );
// uncomment for testing it
//      radioGroup.addValueChangeListener( vc -> {
//         Notification.show("bean enum value: "+ bean.getRadioButtonValue() );
//      });

如果无法将 booleans 更改为 enum 那么我认为最简单的方法是稍微更改上面的内容:

  1. 完全不绑定广播组
  2. 实现 ValueChangeListener,根据所选枚举在 bean 中设置相应的布尔值。