sialcasa / mvvmFX

an Application Framework for implementing the MVVM Pattern with JavaFX
Apache License 2.0
495 stars 104 forks source link

Crossfield validation's strange behaviour - freeze #622

Open daniel-sarov opened 3 years ago

daniel-sarov commented 3 years ago

Currently I'm using mvvmfx validation ver.1.8.0 for my app. I have two PasswordFields named 'password' and 'confirmPassword' in View ,to which two string properties are binded from the ViewModel.

I do the following validation:

Validator passwordValidator = new BlankTextValidator(password, getValidationBundle().getString("cannot_be_blank"));

where BlankTextValidator is:

public class BlankTextValidator extends FunctionBasedValidator {

private static final Predicate<String> isNotBlank = input -> !UtilMethods.isBlank(input);

public BlankTextValidator(ObservableValue<String> source, String message) {
    super(source, isNotBlank, ValidationMessage.error(message));
}

}

I use this validator in quite many places and it works just as expected. For confirmation I use ObservableRuleBasedValidator:

BooleanBinding confirmPasswordNotBlank = Bindings.createBooleanBinding(() -> !UtilMethods.isBlank(confirmPassword.get()), confirmPassword); BooleanBinding passwordMatches = password.isEqualTo(confirmPassword);

ObservableRuleBasedValidator ruleBasedValidator = new ObservableRuleBasedValidator(); ruleBasedValidator.addRule(confirmPasswordNotBlank,ValidationMessage.error(getValidationBundle().getString("password_confirm_required"))); ruleBasedValidator.addRule(passwordMatches, ValidationMessage.error(getValidationBundle().getString("password_mismatch")));

I use CompositeValidator, to which i add the abovementioned valiidators. In View i use ControlsFxVisualizer and also add validation for each control.

ValidationVisualizer visualizer = new ControlsFxVisualizer(); visualizer.initVisualization(adminViewModel.passwordValidation(), passwordField); visualizer.initVisualization(adminViewModel.confirmPasswordValidation(), confirmField);

So far, so good. PasswordField's validation is ok, but comfirmField's validation freezes on first rule, No matter if the field is blank or not. I have tried your implementation from https://github.com/sialcasa/mvvmFX/wiki/Validation . With the same result!

Another strange issue: I use checkcombobox and make validation so that at least one of the fields of the list is checked. In this case i bind every checkbox to BooleanProperty in ViewModel.

The Validation:

public class CheckComboBoxValidator extends ObservableRuleBasedValidator {

public CheckComboBoxValidator(Collection<BooleanProperty> booleanProperties, String message) {
    ObservableValue<ValidationMessage> hasAtLeastOneCheck = Bindings.createObjectBinding(() -> {
        boolean hasAtLeastOneChecked = booleanProperties.stream()
            .anyMatch(bp -> bp.getValue().equals(true));
        if (!hasAtLeastOneChecked) {
            return ValidationMessage.error(message);
        }
        return null;
    }, booleanProperties.toArray(new BooleanProperty[0]));

    addRule(hasAtLeastOneCheck);
}

}

The Validation works, but checkcombobox freezes(becomes not responsive) in case of :

  1. There are peviously checked fields (by default)
  2. Then the user unchecks all of them. The problem resolves when the user selects another control.
manuel-mauky commented 3 years ago

Hard to tell what the problem is. Can you create a minimal example that I could use to debug the issue? Or a failing test case maybe?

daniel-sarov commented 3 years ago

Sorry for not writing right away. I solved my first issue - the mistake was mine. But the second issue with CheckComboBox is still valid. I will try to create a minimal example for you to use.