Form Data Binding

I’ll start out by saying that I’m fairly new to Vaadin, I love it, and Vaadin 7 looks to be a huge improvement on 6 (and that was good enough :grin:)

I want to bind a FieldGroup to a Java bean that has standard getter and setter methods but no underlying field associated with the property name.

E.g. In the following MyBean, I want to bind the property, not field, ‘blah’ to a TextBox within a Form.


public class MyBean() {
    
    private InnerBean innards;

    public String getBlah() {
        return innards.getBlah();
    }

    public void setBlah(String blah) {
        innards.setBlah(blah);
    }
}

In Vaadin 6 this was pretty simple, just shove MyBean into a BeanItem, and then set it as a Form’s datasource (and then optionally specify a FieldFactory and/or visible properties)

In Vaadin 7, where you have to manually create the FieldGroup it doesn’t work, because there’s obviously no underlying field.

So my question is how would you bind something like MyBean into a Form like thing in Vaadin 7, without manually creating the correct type of Field and manual binding for each property.

Many thanks,

Chris

Hi Chris.

In vaadin 7 the binding of bean data to the form uses BeanFieldGroup<?> and works something like this:


		final BeanFieldGroup<MyBean> binder = new BeanFieldGroup<MyBean>(MyBeanclass);
		final FormLayout form = new FormLayout();

		// Add bean item that is bound.
		binder.setItemDataSource(myBean);

		form.addComponent(binder.buildAndBind("caption", "blah"));

More details can be found in

9.4. Binding Fields to Items

9.4.5. Binding Fields to a Bean

Thanks for your reply.

I’m not entirely sure that that works though, if the Bean that you’re binding to doesn’t have an underlying Java Field.
In my understanding when you call buildAndBind it tries to determine the property type by investingating the underlying field on the bean with the given property identifier.
If, as I described, the JavaBean that you’re binding to doesn’t have an underlying field for that property name (which I believe is a perfectly valid JavaBean), the bind fails because it is unable to determine the property type.

I think if we’re talking about Beans as in ‘JavaBeans’ then the
Properties
should be accessed using PropertyDescriptors (and therefore accessor methods) rather than
Fields
and Reflection.

Please let me know if I’ve misunderstood the code and I’m being completely stupid, or I’m attempting to do something the incorrect way.

BeanFieldGroup asks the Item for the property type if the item is set, and only checks the declared type of the field directly if the item data source is not yet set.

Thus, the sample code where an item data source set before binding should work, as BeanItem uses Introspector.getBeanInfo(). Note that you can still change the item data source after performing the binding.

Ahh… fantastic, thanks.

I still find it quite wierd that it tries to determine type by reflection in this way for JavaBeans, rather than PropertyDescriptors and method signatures.

I agree that BeanFieldGroup, as the name suggests, should be able to get the property type using the same mechanism as BeanItem (java.beans.Introspector and some tricks to handle a peculiarity in how it handles interfaces).

Could you
create an enhancement request
about that so that this will not be forgotten.

Ticket raised: http://dev.vaadin.com/ticket/10672

Hello,

confirming this is still the case in 2017. (in Vaadin 7.7.11).
Solution that I found to be working is to explicitly set @PropertyId anotation on the member that’s missing it’s counterpart on the bean.
Ie. something like:

@PropertyId("memberField")
TextField memberField;