Two way binding using FieldGroup

Hi,

I am a little confused due to some strange behavior when I try to use a PropertysetItem as a data model for my GUI together with the FieldGroup class.

I have the following code written to understand the general working principles.

//First I define an sort of data model to be used by the GUI.
final PropertysetItem data = new PropertysetItem();        
data.addItemProperty("name", new ObjectProperty("", String.class));
data.addItemProperty("age", new ObjectProperty(0, Integer.class));
data.addItemProperty("result", new ObjectProperty("", String.class));

//This actually works as expected because I can see -10 as value for
//the GUI component linked below.
data.getItemProperty("age").setValue(-10);

//I create the different GUI components I wish to use to display the info.
final TextField result = new TextField("Result:");
final TextField name = new TextField("Enter your name:");
final TextField age = new TextField("Enter your age:");
layout.addComponent(result);
layout.addComponent(name);
layout.addComponent(age);
name.setRequired(true);
age.setRequired(true);

//Next I bind the different components to the model created earlier.       
final FieldGroup group = new FieldGroup(data);
group.bind(result, "result");
group.bind(name, "name");
group.bind(age, "age");

//Some additional code to do validation and to add converters left behind.
....

//Next I create a button to do some user interaction
Button button = new Button("Click Me");
button.addClickListener(new Button.ClickListener() {
    @Override
    @SuppressWarnings("CallToPrintStackTrace")
    public void buttonClick(ClickEvent event) {
        try{ 
            //Synchronize the state of the GUI with the item (model)    
            group.commit();                    

            //Retrieve the values from the model.
            String strName = (String)data.getItemProperty("name").getValue();
            Integer intAge = (Integer)data.getItemProperty("age").getValue();

            //Do some logic on the backend. The correct values as entered in the GUI
            //are returned. So far, so good.
            String msg = bean.greet(strName, intAge);
            Label label = new Label(msg);
            layout.addComponent(label);

            //Updates the GUI component as expected but I wish to prevent this approach.
            //((TextField)group.getField("result")).setValue(msg);

            //Does NOT update the GUI component which is what I don't expect.
            //Shouldn't the GUI component be updated with the value of msg?
            data.getItemProperty("result").setValue(msg);

        }catch(FieldGroup.CommitException ex){
            //Error notification left behind to reduce the amount of code...
            .....
        }catch(Exception ex){
            //Error notification left behind to reduce the amount of code...
            .....
        }
    }
});
layout.addComponent(button);

As mentionned in the comments, I expect the result component to be updated with the value passed to the setValue() method which is not happening. When I call a setValue()-method on the PropertysetItem before the FieldGroup binding, everything works as expected. Doing so afterwards, does not update the GUI. The content of the model is updated as expected.

I surely must be overlooking something, but I don’t see what I’m actually doing wrong.

And earlier post mentionned to disable buffering, but this interferes with my validators causing exceptions on application startup.

Any suggestion will be greatly appreciated.

Regards,
Kurt

Maybe a second commit is necessary.

Computer says “Nooooo”

I tried to modify the code before the catch into

data.getItemProperty("result").setValue(msg); group.commit() This doesn’t solve the problem though…

Your code should work, but there are a couple of if’s. The easiest way to check is them to put a breakpoint in AbstractField::valueChange(Property.ValueChangeEvent) and see what happens when you set the property value. The property should call that method when you call setValue().