Archive for September 2007

 
 

Private Mixin Interfaces

One additional feature of my binding library is that a Mixin can register any number of interfaces to a presentation model. This allows the Mixin to define implementation properties that aren’t visible to the user. Thus code completion on the ValueModels returned from the PresentationModel won’t show the private properties.

I use this feature in the ValidationMixin. The mixin registers its own interfaces with the PresentationModel being validated. This means you don’t even need to define that your PresentationModel vends ValidatableValueModels. The following is an example.

// Create a model that vends ComponentValueModels defined by
// the ComponentMixin.
public class PersonPM
extends BeanPresentationModel
{
   public PersonPM()
   {
      // we have to pass the classes in because of erasure..
      super(Person.class, ComponentValueModel.class);   

     // create a validation engine, this will install the required
     // mixin interfaces to the presentation model.
     engine = new ValidationEngine(this);  

     // now we can add some values..
     installValueModel("firstName");

     // now configure the validators, these will use the private
     // interfaces defined by the validation mixin.
     engine.getValidationManager("firstName")
           .setMandatory("Please enter your first name")
           .addValidator(new NameValidator());
  }
}

DIY Whiteboard

I can’t live without a decent whiteboard, so I recently built one in my home office. Very cool.

DIY Whiteboard

Whiteboard - $29
Delivery - $33
Sticky stuff to mount it - $30

Being able to draw all over your walls.. priceless.

(c:

GUI Commands Personal License Now Available

A new Personal License has been released for individuals wishing to use GUI Commands for commercial purposes. The new license is available for $15 (US).

For more information please visit the GUI Commands website

Playing with ANTLR

One aspect that can be annoying when creating value models creating bindings for their enabled and visible states. The following shows a simple example where certain components are enabled and disabled based on the value of others.

Mr Schedule Options

In this screen, the “Use Proxy” is only enabled when “Automatically Check for Updates” is selected, and both the “Host” and “Port” fields are only enabled when both check boxes are selected.

To simplify this kind of operation I’ve been playing around with ANTLR grammars. First off, if you’re like me and have never built a language parser before, just go ahead and buy the book. Building an abstract syntax tree would have been near impossible without it.

So far I’ve been able to get a basic language up and going. The syntax is simple and lets you assign model properties from simple expressions involving other models, for example:

useProxy.enabled = checkForUpdates.value

This binds the enabled property of “useProxy” to the value of “checkForUpdates”. I also let you omit the “.value” for simplicity, so then we get:

useProxy.enabled = checkForUpdates

So state of the all the components in the above image is controlled by the three “bind” lines of code in the PresentationModel.

// install the value models...
installValueModel("checkForUpdates", ..);
installValueModel("useProxy", ..);
installValueModel("proxyHost", ..);
installValueModel("proxyPort", ..);

// and create the bindings
bind("useProxy.enabled = checkForUpdates");
bind("proxyHost.enabled = checkForUpdates && useProxy");
bind("proxyPort.enabled = checkForUpdates && useProxy");

Normally I don’t like putting code in strings, but in this case I think it’s worth it. To limit any possible issues the library barfs during the call to bind if any of the models are missing or don’t define the required properties.

And then there were Mixins

One of the key goals for my binding infrastructure has been to make it easy to extend the value models to suit your business requirements. The idea was let you define a custom value model properties and have the library automatically manage them. I had this working pretty well, but it was pretty painful to set up, and definitely not something I’d wish on others.

Enter Mixins. Somewhere along the line it occurred to me that I could create Mixins that provide standard ValueModel extensions and their handlers out of the box. The first test was to convert my ComponentValueModel interfaces that defines standard component properties such as enabled, editable and visible.

public interface ComponentValueModel extends ValueModel
{
    @DefaultValue(true)
    public boolean isEnabled();
    public void setEnabled(boolean enabled);

    @DefaultValue(true)
    public boolean isEditable();
    public void setEditable(boolean editable);

    @DefaultValue(true)
    public boolean isVisible();
    public void setVisible(boolean visible);
}

Using this mixin is now as simple as..

// install the mixin that defines the ComponentValueModel
// interface and standard handlers.
Pectin.registerMixin(ComponentMixin.instance());

// create a presentation model that vends ComponentValueModels
pm = new BeanPresentationModel<Person, ComponentValueModel>(...);

// all the value models returned by the presentation model will
// implement the mixin interface.
ComponentValueModel cvm = pm.get("firstName");

// changes to the mixin properties will be automatically handled
// by the mixin
cvm.setEnabled(true);
cvm.setEditable(false);
cvm.setVisible(true);

From here the mixin is responsible for updating the state of components bound to ComponentValueModels. The mixin uses styles that map particular model properties to particular components allowing you to control the way particular properties effect particular components.

So far I’m really pleased with the progress.