Hi folks.
I got some domain model - for simplicity's sake, let's take a simple order:
public class Order {
List<Position> positions;
double lumpSum;
... accessor methods, etc. ...
}
public class Position {
double itemPrice;
int amount;
String description;
... accessor methods, etc. ...
}
That stuff is shown in an editor - Text controls for the values and so on. In particular there is a table viewer that lets the user select one order position to modify. Fields are mapped to model objects via JFace databinding.
...
final IObservableValue selectedPos = ViewersObservables.observeSingleSelection(positionTableViewer);
// Binding is done mostly using detail values of the selected position.
// E.g. the order position's amount.
IConverter intToString = new IntToStringConverter();
IConverter stringToInt = new StringToIntConverter();
masterDetailContext.bindValue(SWTObservables.observeText(amountText, SWT.FocusOut),
BeansObservables.observeDetailValue(selectedPos, "amount", int.class),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE).setConverter(stringToInt),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE).setConverter(intToString));
// And the description text - note the length validation.
IValidator lengthValidator = new StringLengthValidator(descriptionText, 55);
masterDetailContext.bindValue(SWTObservables.observeText(descriptionText, SWT.FocusOut),
BeansObservables.observeDetailValue(selectedPos, "description", String.class),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE).setAfterGetValidator(lengthValidator),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
...
Our validators change the background color of the field in trouble and show a balloon tip detailing the problem. So when the user in our example writes a very long description for the selected position, the validator kicks in and a balloon tip appears. Because the return code of the validation method is ValidationStatus.error("Some Text"), NO update is performed from the text field to the model. That causes an annoying problem: when the user switches the selected position now, the field remains in the error state and the description text of the old position is still displayed despite the backing object changed.
I worked around the issue with this code:
selectedPos.addValueChangeListener(new IValueChangeListener() {
@Override
public void handleValueChange(ValueChangeEvent event) {
IObservableList bindings = masterDetailContext.getBindings();
for (int i = 0; i < bindings.size(); i++) {
Binding binding = (Binding) bindings.get(i);
IStatus status = (IStatus) binding.getValidationStatus().getValue();
// !! Without that check, the code runs awfully slow. :o\
if (!status.isOK()) {
binding.updateModelToTarget();
binding.validateTargetToModel();
}
}
}
}
Is anyone out there who solved this in an elegant way?