Automatically bind Enum Array with BeanFieldGroup

Hi,

I’m trying to create a form based on a particular class and in this class some variables are enums.
As a consequence I followed this topic(
https://vaadin.com/forum#!/thread/4516099
) which shows how to display a special field for these variables.
Thing is, while it does work with

MyEnum enum; It doesn’t with

MyEnum enums; And I constantly get

Unable to build a field of type com.vaadin.ui.OptionGroup for editing [Lcom.bnpparibas.eqd.common.job.PrsJobStatus; at com.vaadin.server.VaadinService.handleExceptionDuringRequest(VaadinService.java:1460) at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1414) at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:305) ... Which indeed shows that we can’t build an OptionGroup with a array of values.

That’s why I tried with the other AbstractSelect components, such as :

  • ListSelect
  • ComboBox
  • NativeSelect (supposed to accept multiple values)

But still get the error.

Any idea ? :slight_smile:
Thanks.

Please show more of your code. What do you want to achieve?

Ok, I made up an example :

//The class I want a form based on
public class MyTestClass {

    private String value;
    private MyEnum myEnum;
    private MyEnum[] myEnums;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public MyEnum getMyEnum() {
        return myEnum;
    }

    public void setMyEnum(MyEnum myEnum) {
        this.myEnum = myEnum;
    }

    public MyEnum getMyEnums() {
        return myEnums;
    }

    public void setMyEnums(MyEnum myEnums) {
        this.myEnums = myEnums;
    }
}

//The enum I want displayed as a selector component public enum MyEnum { ONE, TWO, THREE } [code]
//The builder of my form
public class MyFormBuilder {

private final BeanFieldGroup<T> binder;
private final List<String> fields = new ArrayList<String>();

public MyFormBuilder(String name, T bean) {
    binder = new BeanFieldGroup(bean.getClass());
    binder.setItemDataSource(bean);
}

public MyFormBuilder<T> addProperty(String name) {
    fields.add(name);
    return this;
}

public FormLayout build() {
    FormLayout form = new FormLayout();

    for (String field : fields) {
        if (field.equals("myEnum")) {
            form.addComponent(binder.buildAndBind("MyEnum", "myEnum", OptionGroup.class));
        } 
        //this one throws an exception
        else if (field.equals("myEnums")) {
            form.addComponent(binder.buildAndBind("MyEnums", "myEnums", OptionGroup.class));
        } 
        else {
            form.addComponent(binder.buildAndBind(field));
        }
    }

    // **** IRRELEVANT CODE **** //
    return form;
}

}
[/code][code]
//How I create the form

MyTestClass test = new MyTestClass();
TitanFormBuilder<MyTestClass> builder = new TitanFormBuilder<MyTestClass>("test", test);
builder.addProperty("value");
builder.addProperty("myEnum");
builder.addProperty("myEnums");

[/code]I want to be able to choose value(s) from a component such as OptionGroup that has been fed with MyEnum values.

Thank you ! :slight_smile:

Should the type of myEnums be MyEnum instead of MyEnum?

Yeah, sorry, edited.

So basically, you want to be able to multiselect multiple MyEnum values in the option group bound to myEnums, instead of just one?

Yes, like that (example with a Vaadin 6.x component)

Image attached.
16614.png

Okay, Vaadin doesn’t (and can’t) by default know what to do with an array-typed property, so you’ll have to tell it.

First off, if possible, consider using a Set instead of a MyEnum as the type of your property. The values of Vaadin multiselect fields are Sets, so using a matching type saves you the trouble of writing a custom Converter.

Second, the default FieldFactory doesn’t know to create a multiselect Field when given a property of a Collection/array type, so you’ll want to either write a custom FieldFactory or create the field manually:

OptionGroup og = new OptionGroup("MyEnums", EnumSet.allOf(MyEnum.class));
og.setMultiSelect(true);
binder.bind(og, "myEnums");
form.addComponent(og);

Thank you it worked.