Vaadin table with combobox selected value problem

Hey guys i am new to vaadin and i am currently developing my first vaadin application.

I have a table with 3 columns with text. The data comes from a BeanItemContainer of my own user class. In editing mode of the table I want to change the type of one column to a ComboBox with some values to choose from.

In the user class i have a Property for the userrole:

public class User {
    private String username;
    private String password;
    private Boolean active = true;
    private Role role;

...... getter and setter...
}

And my class for the roles:

public class Role {
    private String rolename;

..... getter and setter...
}

In the View I bind the data to the table and adding the TableFieldFactory to get my ComboBox in editing mode:

tblUsers.setContainerDataSource(users);
...
tblUsers.setTableFieldFactory(new DefaultFieldFactory() {
            @Override
            public Field createField(Container container, Object itemId,
                    Object propertyId, Component uiContext) {
                if ("role".equals(propertyId)) {
                    final ComboBox select = new ComboBox();
                    select.setImmediate(true);
                    select.setNullSelectionAllowed(false);
                    BeanItemContainer<Role> roles = ComponentHelper.getDummyRoles();
                    select.setContainerDataSource(roles);
                    select.setItemCaptionPropertyId("rolename");
                    return select;
                }
                
                return super.createField(container, itemId, propertyId, uiContext);
            }
        });

In the editmode I am getting my ComboBox filled with the values, but I am not able to set the selected Value of the ComboBox. The default selected value is always null. The ComboBox should be selected with the value shown in the not editable table view.
Two pictures of my current state (edit and non edit view):
http://www.directupload.net/file/d/3776/2meo4gyb_jpg.htm
http://www.directupload.net/file/d/3776/8jaznu95_jpg.htm

How can i set the selected value in my ComboBox? Is there a better way to get nested object into a editable table?

I also have a problem like that.

I have tried to use these functions: combobox.setValue and combobox.select. But they don’t work.
Here you go my code, any idea?

[code]
group = new ComboBox("Group: ");
group.setContainerDataSource(groups);

    if(editedUser.getGroup()!=null){
        group.setValue(editedUser.getGroup());
    }

[/code]Thanks!

I have limited the problem that I have.
Exactly, I’m using BeanItem so that is the reason which I couldn’t set the value of Combobox.

Did anybody have a problem like this?

 private Component buildForm() {
           ...
            ComboBox group = new ComboBox("Group:");

            List<Group> groups = GroupService.findAll();           
            Iterator it = groups.iterator();
            while (it.hasNext()) {
                Group grp = (Group) it.next();              
                group.addItem(grp.getId());
                group.setItemCaption(grp.getId(), grp.toString());
                it.remove(); // avoids a ConcurrentModificationException
            }
            
            fieldGroup.bind(id, "id");
            ...
            fieldGroup.bind(group, "group");  

           ...        

            form.addComponent(username);
            ...
            form.addComponent(group);           
}



 private void editUser(User user) {
            if (user == null) {
                user = new User();
            }            
            BeanItem<User> item = new BeanItem<User>(user);           
            fieldGroup.setItemDataSource(item);
}

I did not find a solution but a workaround.
Instead of using the editable table I open a new window with the fields I want to change.
In the window I have no problem to set the ComboBox to the value of the BeanItem.

Hi Juri!

First of all, trying to set values in a field factory will be overwritten by the table setting the propertydatasources. You are not doing that, but just as a pointer on where not to try to do it.

Anyway, you seem to get the roles from another source: BeanItemContainer<Role> roles = ComponentHelper.getDummyRoles(); And my guess is that these roles are not the same objects as found in the user collection. What happens, is that the table sets the propertydatasource from user.role, which has probably been instantiated otherwhere. You COULD do so that you have a static list of the roles and always using these to ensure the correct objects are matching between the propertydatasource and the containerdatasource.

However, the best approach would probably be to override Role.equals(Object) and the Role.hashcode(). I would do it somehow like this:

[code]
@Override
public boolean equals(Object obj) {
if (obj == null) { // null vs not null, never equals
return false;
}
if (!(obj instanceof Role)) { // Not even the same type
return false;
}
Role other = (Role) obj;
if (rolename == null && other.rolename == null) { // if both rolenames are null, it is ok
return true;
}

        if (rolename == null || other.rolename == null) { // if only one is null, not ok
            return false;
        }
        return rolename.equals(other.rolename); // let the value of the string decide
    }

[/code]And

@Override public int hashCode() { return rolename.hashCode(); } Please try this out and tell me if it helped.

Best regards,
Johan

Hey Johan,

I used a static class for creating my example data in memory.

Now i switched to Hibernate and I changed my code to use FieldGroup. The code

fieldGroup.bind(cbRoles, "rolle")

does all the required job for me in a seperate window.I will try your code later on to get my ComboBox working in the Table.

Hi

I have pretty much the same situation, working with BeanItemContainer and wanting to put one particular attribute of a domain class in combobox.
After looking for a long time, I finally found this thread, tried Johan’s solution of overwriting the equals() and the hashCode() method of my domain class.
Even though I also read somewhere else, that one should not initialize the ComboBox in the setTableFieldFactory() method of the table (since the data binding is done by the table once we pass it the BeanItemContainer with the setContainerDataSource() of the table), I gave it a try never the less:

table.setTableFieldFactory( new TableFieldFactory () {

   @Override
   public Field createField(Container container, final Object itemId, final Object propertyId, Component uiContext) {
      Field editorField

      //<some logic>

      comboBox.setInvalidAllowed(false)
      comboBox.setNullSelectionAllowed(false)
      Collaborator.findAll().each {
         comboBox.addItem(it)
      }
      Collaborator currentOwner = ((CollaboratorGroup)itemId).getOwner()
      comboBox.select(currentOwner)
      editorField = comboBox

      //<some more logic>

      return editorField
}

the Collaborator domain class is where I overrode the equals() and the hashCode() methods (obviously the owner of a CollaboratorGroup is a Collaborator foreign key). I also did an override on the toString() method b.t.w. not necessairy, but more readable.

So that worked for me. Thanks Johan