Introducing the BindSpec
Up to this point in this tutorial, as well as Part 2, you've seen instances of BindSpec created with no other follow-up information provided. Sometimes, when you're binding the properties of two objects, more configuration is needed to achieve the desired data flow back and forth. This is where the BindSpec class comes in. It serves as a way to specify more binding configuration, as well as provide validation and conversion functionality during data synchronization.
Looking at the BindSpec class, you'll see that it contains setter methods for model-to-target and target-to-model converters. Each method requires a class implementing the IConverter interface, shown in Listing 12.
Listing 12. The IConverter interface
public interface IConverter {
public Object getFromType();
public Object getToType();
public Object convert(Object fromObject);
}
|
To allow JFace data binding to check that you've specified a valid converter for the target and model being bound, the interface requires types for each side of the conversion. Normally, this is something like String.class. The DataBindingContext.bind method then compares these types against the types of the model and target at bind time for consistency. The only other method required does the actual conversion.
The other main option on the BindSpec is that of a validator. Validators can be set on the target and model sides. Calling setValidator defaults to the target side. This causes data from a widget, for example, to be validated before being synchronized with a model. Validators must implement the IValidator interface shown in Listing 13.
Listing 13. The IValidator interface
public interface IValidator {
public ValidationError isPartiallyValid(Object value);
public ValidationError isValid(Object value);
}
|
The isPartiallyValid() method allows you to perform validation while a value is being changed -- for example, while a text field has focus and the user is typing. The isValid() method, in comparison, is invoked after all changes have been made, but before synchronization with the model -- for example, tabbing off a text field.


