Nested binder with nested layouts

Hi all,
what is the best approach to manage complex layouts (composed by nested layout, each one with its own binder)?

if I have this: [code]
class Person {
String fistName;
String lastName;
Address address;
}

class Address {
String city;
String street;
}
[/code]And i have a complex UI, with many sections, and one section show Person info, and another one show Address info.
So there will be 2 different class, one for PersonLayout, and one for AddressLayout, and each of these class has its own binder.
But I don’t know how to manage the saving of the Person. I can have a button on the main UI (the class that contains the 2 layouts) and I can do something like:

saveButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent event) { Address address = addressPanel.getAddress(); Person person = personPanel.getPerson(); person.setAddress(address); service.save(person); } }); where in PersonLayout I have:

public Person getPerson() { return binderPerson.getBean(); } and in AddressLayout I have:

public Address getAddress() { return binderAddress.getBean(); }

But I don’t know if it’s a good approach and when the main layout will be more complex, with many sublayouts, I guess the code will be more messy.
So i would like to know if there is a better approach, when there is a complex UI, composed by many smaller layouts, each one representing a nested property of the same object, and how best to implement binder in such case.

Thank you in advance

Nobody have found this problem?
Any time that we have a complex UI, composed by multiple subforms, you always use one binder for all the view?
Or maybe it’s not good to have distinct class for ech sub form or sub panel, and include everything in one big class with only one binder?

It is tricky. I am going to try to give you the basic idea.

  1. You need a wrapper class for both
    Person
    and
    Address
    classes something like this.

[code]
public WrapperClass {

private Person person;
private Address address;

public WrapperClass() {}

public Person getPerson() { return person; }
public void setPerson(Person value) { person = value; }

public Address getAddress() { return address; }
public void setAddress(Address value) { address = value; }

}
[/code]2) You need to create two
CustomField
fields for
Person
and
Address
.
Here
you can find basic
CustomField
information. Something like this:

[code]
public class PersonField extends CustomField {

...

//these are must be overriden
doSetvalue
getValue
initContent

}

public class AddressField extends CustomField {

...

//these are must be overriden
doSetvalue
getValue
initContent

}
[/code]3) You need to bind the two custom fields to the data with
Binder
as you do while binding a
TextField
. While the app is running,
Binder
passes
Person
and
Address
values to the custom fields.

If your custom fields are read only, you can add labels and set the labels’ values as usual:
label.setValue(this.value.personName)

If your custom fields are going to have fields like
TextField
, you need to bind these fields to the custom field with another
Binder
instance.

This is the approach I have found until now. I tried to keep my explanation as clear as possible, hope it helps.

Update: Main
Binder
is going have all data.

Hi, didn’t think about CustomField to represent a whole model…it’s a good idea.
Let me see if i got the trick:

  1. The WrapperClass is a class that wraps all the model that you are showing in the MainLayout view.
  2. You have a Binder, in the MainLayout view that binds all the custom fields (for example Person, Address).
  3. If, for example the CustomField is not readonly, we need to implement a Binder inside the CustomField class.

When I have to save all, so for example with a button inside the MainLayout, i need to do something like this:

public void saveAll() { Address address = addressCustomField.getValue(); Person person = personCustomField.getValue(); person.setAddress(address); service.save(person); That is similar to what i did before, but better because i don’t have to implement custom method inside the sub views (for example getAddress() and getPerson()), but i can use directly the getValue provided by CustomField class.
What sounds not good, is the fact that in the saveAll() method, i have to composite the Person +Address, instead of having a direct way to get all the model in one shot from the binder. Or maybe i’m missing something here.

Just save
WrapperClass
. The tricky part is
Binder
s inside the custom fields are going to update
WrapperClass
. This approach is helpful when there is one person has two contact informations.