javadata-bindingjfaceeclipse-databinding

JFace/Eclipse databinding trigger multivalidator in ChangeListener of AggregateValidationStatus


I have an AggregateValidationStatus with an IChangeListener. The listener is called every time I select/change and component which is what I need. The only problem I have is that I have to trigger the validate() method of my MultiValidator in the beginning of the ChangeListener. Sadly there is very low documentation and what I found didn't help me.

My ChangeListener

final AggregateValidationStatus aggregateValidationStatus = new AggregateValidationStatus(
        dataBindingContext.getBindings(), AggregateValidationStatus.MAX_SEVERITY);
aggregateValidationStatus.addChangeListener(new IChangeListener() {
    public void handleChange(ChangeEvent event) {
        //Here I have to trigger the MultiValidator to return either OK or ERROR
        boolean formIsValid = true;
        aggregateValidationStatus.getValue();
        for (Object o : dataBindingContext.getBindings()) {
            Binding binding = (Binding) o;
            IStatus status = (IStatus) binding.getValidationStatus().getValue();
            if (!status.isOK()) {
                formIsValid = false;
            }

            Control control = null;
            if (binding.getTarget() instanceof ISWTObservable) {
                ISWTObservable swtObservable = (ISWTObservable) binding.getTarget();
                control = (Control) swtObservable.getWidget();
            }
            if (binding.getTarget() instanceof CalendarComboObservableValue) {
                CalendarComboObservableValue observable = (CalendarComboObservableValue) binding.getTarget();
                control = (Control) observable.getControl();
            }

            if (binding.getTarget() instanceof IViewerObservable) {
                IViewerObservable observable = (IViewerObservable) binding.getTarget();
                control = observable.getViewer().getControl();
            }

            ControlDecoration decoration = decoratorMap.get(control);
            if (decoration != null) {
                if (status.isOK() || status.matches(Status.WARNING)) {
                    decoration.hide();
                } else {
                    decoration.setDescriptionText(status.getMessage());
                    decoration.show();
                }
            }
        }
        if (saveBtn != null)
            saveBtn.setEnabled(formIsValid);
    }
});

Solution

  • Your AggregateValidationStatus only aggregates over the bindings of the datBindingContext:

    final AggregateValidationStatus aggregateValidationStatus = new AggregateValidationStatus(
        dataBindingContext.getBindings(), AggregateValidationStatus.MAX_SEVERITY);
    

    The MultiValidator is not attached to a single binding but to the whole context. So if you want your AggregateValidationStatus to monitor MultiValidators as well, you should use a different constructor:

    final AggregateValidationStatus aggregateValidationStatus = new AggregateValidationStatus(
        dataBindingContext, AggregateValidationStatus.MAX_SEVERITY);
    

    This should make the manual trigger of the MultiValidator in handleChanged superfluent.