PATRY Guillaume
PATRY Guillaume

Reputation: 4337

Nested bean : a collection inside an object

I got a simple POJO class that i wish to display / update in a form
Using the BeanItem class and the binding of component data, i was able to quickly display the first attributes of may data class. However i've hit a wall for tow related attributes :

my class posses a set of available status, as a list of object 'AppStatus'. it also possess a current status, that is one of the status in the 'available' list.

I would like to display the list in the form as a combobox, with the current status selected.

I'we managed to associate the 'available' attribute with a combobox, but i can't seem to be able to fill this combobox when setting the data source (method setItemDataSource). How do i get the avalaible status list and the current status from my Item ?

I could always use a workaround and add a parameter to the method to get the source objet in addition to the BeanItem, but i would prefer to avoid this if the Item properties can give me my attribute.

Regards

Edit : shortened exemple, with code from Eric R.

class Status {
   String id;
   Sting label
+ setter /getter
}

class App {
   String AppId;
   String AppLabel
   ArrayList<Status> availablestatus;
   Status currentStatus
+setter/getter
}

in the form extension, in the createField of the fieldfactory i added the following lines

if ("status".equals(propertyId)) {
// create the combobox
   ComboBox status = new ComboBox(
      texts.getString("application.label.status"));
   status.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
   status.setItemCaptionPropertyId("label");
   status.setImmediate(true);
   status.setNullSelectionAllowed(false);

   IndexedContainer container = new IndexedContainer(
      (Collection<ApplicationStatus>) item.getItemProperty(
      "availableStatus").getValue());

   status.setContainerDataSource(container);
   status.setPropertyDataSource(item.getItemProperty("currentStatus"));

   return status;
} else...

this didn't work, i do get a combobox, with the correct number of lines, but all empties.

i tried to use a beanContainer instead of a IndexedContainer

  BeanContainer<String, ApplicationStatus> container = 
      new BeanContainer<String, ApplicationStatus>(ApplicationStatus.class);
   container.addAll((Collection<ApplicationStatus>) item
          .getItemProperty("availableStatus"). 
   container.setBeanIdProperty("id");

the result is slightly better, since i do have the available values in the combobox. only the currentValue is not selected...

I also tried to use a nestedbean property to get the id of the currentstatus, but the result is still not valid... i get a combobox, with the correct value selected, but i can not see others values anymore, since the combobox is readonly ?(even with setReadOnly(false);)

Upvotes: 1

Views: 4199

Answers (2)

user973999
user973999

Reputation:

I suggest my way to resolve this. I don't think this is the nicest way, but it's works.

The beanItem class contains all you need.

I did the following in a simple project and it's work verry well :

         ComboBox status = new ComboBox("ComboBox");
    status.setImmediate(true);
    status.setNullSelectionAllowed(false);

    for(Status st : (Collection<Status>)item.getItemProperty("availableStatus").getValue()) {
        status.addItem(st);
        status.setItemCaption(st, st.getLabel());
    }
    status.setPropertyDataSource(item.getItemProperty("currentStatus"));

Hope it's works.

Regards Éric

Upvotes: 1

Marthin
Marthin

Reputation: 6543

From the vaadin demo site you can get this sample that show how to fill a combobox with countries. You could do the same i would guess (not sure I understand your problem 100%):

myForm.setFormFieldFactory(new MyFormFieldFactory ());

private class MyFormFieldFactory extends DefaultFieldFactory {

        final ComboBox countries = new ComboBox("Country");

        public MyFormFieldFactory () {
            countries.setWidth(COMMON_FIELD_WIDTH);
            countries.setContainerDataSource(ExampleUtil.getISO3166Container());
            countries
                    .setItemCaptionPropertyId(ExampleUtil.iso3166_PROPERTY_NAME);
            countries.setItemIconPropertyId(ExampleUtil.iso3166_PROPERTY_FLAG);
            countries.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
        }

        @Override
        public Field createField(Item item, Object propertyId,
                Component uiContext) {
            Field f = (Field)item;
            if ("countryCode".equals(propertyId)) {
                // filtering ComboBox w/ country names
                return countries;
            }
            return f;
        }
}

Upvotes: 0

Related Questions