Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BeanFieldGroup with ComboBox?

Tags:

java

vaadin7

I'm trying create a ComboBox component using BeanFieldGroup in my application, but still can't do this works. I tried create a combobox first and after add this combobox in buildAndBind but doesn't work also.

I'm trying this:

/** person's bean */
@Entity
public class Person{

@Id
@GeneratedValue
private Integer id;

@NotNull
@NotEmpty
@Size(min=5, max=50, message="insert first name")
private String firstName;

@NotNull
@NotEmpty
@Email private String email;

//female or male
private String gender;

//get and set
}

/** app */
public class PersonView extends CustomComponent{
private final BeanFieldGroup<Person> binder = new BeanFieldGroup<Person>(Person.class);
private Person bean = new Person();

    private ComboBox gender;

    public PersonView(){
         VerticalLayout vLayout = new VerticalLayout();
         Field<?> field = null;
         field = binder.buildAndBind("Gender", "gender", ComboBox.class);
         gender = (ComboBox)binder.getField("gender");
         gender.addItem("Male");
         gender.addItem("Female");
         vLayout.addComponent(gender);
    }
}

Exception:

/** exception /*
Caused by: com.vaadin.data.fieldgroup.FieldGroup$BindException: Unable to build a field of type com.vaadin.ui.ComboBox for editing java.lang.String
    at com.vaadin.data.fieldgroup.FieldGroup.build(FieldGroup.java:1067)
    at com.vaadin.data.fieldgroup.FieldGroup.buildAndBind(FieldGroup.java:1039)
    at br.ind.ibg.views.CurriculumView.buildLayout(CurriculumView.java:50)
    at br.ind.ibg.views.CurriculumView.<init>(CurriculumView.java:32)
    at br.ind.ibg.views.LoginView.buttonClick(LoginView.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
    ... 37 more

How I do this ?

like image 359
FernandoPaiva Avatar asked Apr 15 '14 16:04

FernandoPaiva


1 Answers

Thats a good question! After some investigation I found the following solution:

You have to create your custom FieldGroupFieldFactory (why see below):

binder.setFieldFactory(new DefaultFieldGroupFieldFactory() {

    @Override
    public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {

        if (type.isAssignableFrom(String.class) && fieldType.isAssignableFrom(ComboBox.class)) {
            return (T) new ComboBox();
        }

        return super.createField(type, fieldType);
    }

});

The reason why:

If you have a look at the vaadin source code of DefaultFieldGroupFieldFactory.java you will see that in the end a ComboBox will only be created IF you provide an Enum as "property data source". You provide a String so the DefaultFieldGroupFieldFactory wants to create a TextField. But you provided a ComboBox. In the end there is an Exception thrown.

With your own Factory it will work. Don't forget to setItemDataSource(bean) and commit() your binder to actually write the gender to the bean.

like image 180
nexus Avatar answered Nov 15 '22 11:11

nexus