Change value of a bean inside a bean in a BeanItemContainer

Hi everyone,
I have totally no idea how to do this, and i tried (in my opinion) everything to get it done…

Let’s make an example:
There are two entities

public class Address {
    private City city;
    private String street;
    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

and

[code]
public class City {
private String name;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}
[/code]To show it on grid i create a BeanItemContainer

BeanItemContainer<Address> container = new BeanItemContainer<Address>(Address.class, values); which has properties “street” and “city.name”.

Now i want edit the address so I make a window on which I have a TextField binded to “street” and… and I don’t know how to bind a component to change the city. But… Let’s assume that i have a component which gives me a City object, how to change its value in address object? The BeanItem has a “city.name” property but no “city”. When I’m doing addressBeanItem.getBean().setCity(newCity) the addressBeanItem does not refresh so in grid i have old value.

Help… please :slight_smile:
Thanks in advice.

I think what you’re looking for is something along these lines:

City dallas = new City(); dallas.setName( "dallas" ); addressBean.getItemProperty( "city" ).setValue(dallas); Please see this full sample code:

    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);
        Address address = new Address();
        address.setStreet( "123 street");
        City dallas = new City();
        dallas.setName( "dallas" );
        address.setCity(dallas);
        BeanItemContainer<Address> container = new BeanItemContainer<Address>(Address.class);
        BeanItem<Address> addressBean = container.addItem( address );
        TextField tf = new TextField( "City");
        tf.setConverter( new Converter<String, City>()
            {

                @Override
                public City convertToModel( String value, Class<? extends City> targetType, Locale locale )
                    throws com.vaadin.data.util.converter.Converter.ConversionException
                {
                    City city = new City();
                    city.setName( value );
                    return city;
                }

                @Override
                public String convertToPresentation( City value, Class<? extends String> targetType, Locale locale )
                    throws com.vaadin.data.util.converter.Converter.ConversionException
                {
                    return value.getName();
                }

                @Override
                public Class<City> getModelType()
                {
                    return City.class;
                }

                @Override
                public Class<String> getPresentationType()
                {
                    return String.class;
                }
            
            });
        tf.setPropertyDataSource( addressBean.getItemProperty( "city" ));
        City austin = new City();
        austin.setName("Austin");
        addressBean.getItemProperty( "city" ).setValue( austin);
        layout.addComponent( tf );
    }

Thanks for your answer but sadly it’s not working. Address bean doesn’t have “city” property, it has only “street” and “city.name” so getItemProperty( “city” ) returns null :frowning:

EDIT:
I figured out that the reason why there is no “city” property is

container.addNestedContainerBean("city) 

it removes “city” and adds nested city fields. How can i have city fields on grid and city property container?? :frowning:

EDIT:
When I’m doing

container.addNestedContainerBean("city"); container.addNestedContainerProperty("city"); container has a “city” property and “city.name” property also. But when i’m doing

addressBean.getItemProperty("city").setValue(city); the “city.name” property in grid is obviously not refreshing… No ideas left…

EDIT:
Soo… if anyone is iterested :slight_smile: I made a workaround which works and I’m not happy of it but, well, that’s life.

    List<PropertyDescriptor> propertyDescriptors = BeanUtil.getBeanPropertyDescriptor(cityObj.getClass());
    BeanItem<City> newCityBeanItem = new BeanItem<City>((City) cityObj, City.class);
    Collection<?> beanProperties = addressBean.getItemPropertyIds();
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors)    {
        if (beanProperties.contains("city." + propertyDescriptor.getName())) {
            Object value = newCityBeanItem.getItemProperty(propertyDescriptor.getName()).getValue();
            if (value != null) {
                addressBean.getItemProperty("city." + propertyDescriptor.getName()).setValue(value);
            }
        }
    }