gwtgxtgwt-editors

GWT-Editors and sub-editors


I'm trying to run an example of Editors with sub-editors. When flushing the parent the value of child editor is null. The classes are Person and Address. The main editor is:

    // editor fields
public TextField firstname;
public TextField lastname;
public NumberField<Integer> id;

public AddressEditor address = new AddressEditor();

public PersonEditor(Person p){
    asWidget();
}

@Override
public Widget asWidget() {
    setWidth(400);
    setBodyStyle("padding: 5px;");
    setHeaderVisible(false);

    VerticalLayoutContainer c = new VerticalLayoutContainer();

    id = new NumberField<Integer>(new IntegerPropertyEditor());
    // id.setName("id");
    id.setFormat(NumberFormat.getFormat("0.00"));
    id.setAllowNegative(false);
    c.add(new FieldLabel(id, "id"), new VerticalLayoutData(1, -1));

    firstname = new TextField();
    // firstname.setName("firstname");
    c.add(new FieldLabel(firstname, "firstname"), new VerticalLayoutData(1, -1));

    lastname = new TextField();
    lastname.setName("lastname");
    c.add(new FieldLabel(lastname, "lastname"), new VerticalLayoutData(1, -1));

    c.add(address);
    add(c);
    return this;

The sub-editor:

public class AddressEditor extends Composite implements Editor<Address> {

private AddressProperties props = GWT.create(AddressProperties.class);
private ListStore<Address> store = new ListStore<Address>(props.key());
ComboBox<Address> address;

public AddressEditor() {
    for(int i = 0; i < 5; i ++)
        store.add(new Address("city" + i));
    address = new ComboBox<Address>(store, props.nameLabel());

    address.setAllowBlank(false);
    address.setForceSelection(true);
    address.setTriggerAction(TriggerAction.ALL);
    initWidget(address);
}

And this is where the Driver is created:

private HorizontalPanel hp;

private Person googleContact;
PersonDriver driver = GWT.create(PersonDriver.class);

public void onModuleLoad() {

    hp = new HorizontalPanel();
    hp.setSpacing(10);

    googleContact = new Person();
    PersonEditor pe = new PersonEditor(googleContact);

    driver.initialize(pe);
    driver.edit(googleContact);

    TextButton save = new TextButton("Save");
    save.addSelectHandler(new SelectHandler() {

        @Override
        public void onSelect(SelectEvent event) {
            googleContact = driver.flush();
            System.out.println(googleContact.getFirstname() + ", " + googleContact.getAddress().getCity());
            if (driver.hasErrors()) {
                new MessageBox("Please correct the errors before saving.").show();
                return;
            }
        }
    });

The value of googleContact.getFirstname() is filled but googleContact.getAddress() is always null. What I'm missing?


Solution

  • The AddressEditor needs to map to the Address model - presently, it doesn't seem to, unless Address only has one getter/setter, called getAddress() and setAddress(Address), which wouldn't really make a lot of sense.

    If you want just a ComboBox<Address> (which implements Editor<Address> already), consider putting that combo in the PersonEditor directly. Otherwise, you'll need to add @Path("") to the AddressEditor.address field, to indicate that it should be directly editing the value itself, and not a sub property (i.e. person.getAddress().getAddress()).

    Another way to build an address editor would be to list each of the properties of the Address type in the AddressEditor. This is what the driver is expecting by default, so it is confused when it sees a field called 'address'.

    Two quick thoughts on the code itself: there is no need to pass a person into the PersonEditor - thats the job of the driver itself. Second, your editor fields do not need to be public, they just can't be private.