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 ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With