Hi all,

I've been watching some of the Google IO presentations and have been
learning a lot.  One thing I'm missing from my Swing background is a
nice PresentationModel/ValueModel framework (ala JGoodies binding and
SpringRichClient forms).  ValueModels can do some pretty cool things
using converters/functions/multiplexers etc and can come into their
own when the value model is extended to model "fields" with enabled,
visible, and editable states.  When using this approach the view
classes end up containing only layout and focus ordering code.  All
the functional behaviour is defined by the model (and any associated
Actions/Commands).  I've coded a such a framework more than once
before (for various crazy reasons (c:) and don't really want to do it
all again if I can avoid it so I'm interested to know if anyone else
is pursuing this line?

I've attached some basic usage scenarios of how I'd like to use such a
framework.  In the example FieldModel<T> extends HasValue<T> and would
add bound properties for visible, enabled and editable.

// create ourselves a form model and add some fields to it.  Some get
their values from beans, some from other fields and some just exist on
the form.

public MyFormModel extends FormModel {

     // field bound to a valuemodel (we would need to use deferred
binding to create value models for bean properties)
   // api -> fieldOfType(T.class).boundTo(HasValue<T>).create();
   FieldModel<String> firstName = fieldOfType(String.class).boundTo
(firstNameFakedReflectionThingy).create();
   FieldModel<Gender> gender = fieldOfType(Gender.class).boundTo
(genderFakedReflectionThingy).create();

   // converting to and from other values, user can enter either field
and the other updates automagically.
   // api -> fieldOfType(T.class).convertedFrom(HasValue<S>).using
(Converter<T,S>).create();
   FieldModel<Double> dollars = fieldOfType(Double.class).convertedFrom
(centsField).using(new DollarsToCentsConverter()).create();

   // calculated values
   // api -> fieldOfType(T.class).caculatedFrom(HasValue<S>...).using
(Function<T,S>);
   FieldModel<Double> netWorth = fieldOfType
(Double.class).calculatedFrom(dollarsInWallet,
dollarsUnderMattress).using(Functions.sum()).create();

   // value holder (i.e. a form only value that isn't stored anywhere)
   FieldModel<Boolean> showSecretStashLocation = fieldOfType
(Boolean.class).create();
}

The model becomes more powerful when you add bindings to the enaled/
visible state based on other fields (or values) within the form.  I'd
previously achieved this in Swing using a simple ANTLR based language
embedd in strings (eek), but I always hated the lack of type saftey
and code completiong so I figured the guice inspired builder style api
would probably do the trick.  I.e. to enable a field based on the
value of another field you'd go...

   // Note: the field(..) method returns a FieldConditionBuilder<T>
   // api -> enable(field).when(Condition)
   enable(secretStashAmount).when(field(showSecretStashLocation).value
().is(true))

Then when the field showSecretStashLocation changes, the
secretStashAmount would enable and disable automagically.  And
similarly...
   disable(...).when(...)
   show(...).when(...)
etc.


A similar approach could also be used for validation, although this
widens the api somewhat and you end up having to define interfaces
ValidationResult, IndexedValidationResult and what not.

   // Add some validation...
   // api -> validate(FieldModel<T>).using(Validator<T>).when
(Condition)
   validate(shippingAddress).using(shippingAddressValidator).when(field
(shipToDifferentAddress).value().is(true))

Then once you form model is complete you need to bind you field models
to your form.  Previously when developing this in Swing I've used
explicit binding classes (similar the Karsten Lentzsch of JGoodies
fame), but they are a huge pain to create and maintain.  I'm think the
HasValue<T> interface on GWT widgets should simplify this enormously.

// bring in the bind methods..
import static WidgetBinder.bind;

public MyForm extends Composite {
   // it would be really nice with UIBinder..
   @UiField TextBox firstNameTextBox;
   @UiField RadioButton maleRadioButton;
   @UiField RadioButton femaleRadioButton;
   @UiField CheckBox showSecretStashCheckBox;

   public MyForm(MyFormModel model) {
      // do any the UI binder stuff...
      ...

      // now bind our widgets to our model.
      bind(model.firstName).to(firstNameTextBox);

      // bind radio buttons to specific values...
      bind(model.gender).withValue(Gender.MALE).to(maleRadioButton);
      bind(model.gender).withValue(Gender.FEMALE).to
(femaleRadioButton);

      bind(model.showSecretStash).to(showSecretStashCheckBox);

      // we can also use field models directly to control other parts
of the UI.
      model.showSecretStash.addValueChangeHandler(new
ValueChangeHandler<Boolean>() {
          public void onValueChange(ValueChangeEvent<Boolean> event) {
             secretStashWidget.setVisible(event.getValue());
          }
      }
   }
}

Cheers
Andrew
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to