我有几个TextField和一个提交按钮。我希望禁用所有按钮,除非所有文本字段均已通过验证。下面是我的BooleanBindings代码:

        BooleanBinding firstNameValidation, middleNameValidation, lastNameValidation,
        usernameValidation, passwordValidation, retypePasswordValidation, emailValidation, phoneNumberValidation;

        firstNameValidation = Bindings.createBooleanBinding(()->{
            if(employee.setFirstName(txtFirstName.getText()) == 0){
                piFirstName.setProgress(100);
                return true;
            } else {
                piFirstName.setProgress(0);
                return false;
            }
        }, txtFirstName.textProperty());

        middleNameValidation = Bindings.createBooleanBinding(()->{
            if(employee.setMiddleName(txtMiddleName.getText()) == 0){
                piMiddleName.setProgress(100);
                return true;
            } else {
                piMiddleName.setProgress(0);
                return false;
            }
        }, txtMiddleName.textProperty());


..等等。

这是我尝试将Submit按钮的disableProperty绑定到BooleanBindings的方式:

btnSetPermissions.disableProperty().bind(firstNameValidation.not().or(middleNameValidation.not()).or(lastNameValidation.not())
                .or(usernameValidation.not()).or(passwordValidation.not()).or(retypePasswordValidation.not())
                .or(emailValidation.not()).or(phoneNumberValidation.not()));


它可以工作,但是如果第一个条件返回false,则由于进行“或”运算,因此不会检查其余条件。

我似乎找不到解决方案。任何帮助将非常感激。

最佳答案

您过多地混用了功能。将其分为几个组成部分:

firstNameValidation = Bindings.createBooleanBinding(() -> {
    String firstName = txtFirstName.getText();
    if (/* firstName is valid */) {
        return true ;
    } else {
        return false ;
    }
}, txtFirstName.textProperty());

employee.firstNameProperty().bind(txtFirstName.textProperty());
// if you want employee.firstName to change only if the name is valid,
// use a listener here instead of the binding above:
txtFirstName.textProperty().addListener((obs, oldText, newText) -> {
    if (firstNameValidation.get()) {
        employee.setFirstName(newText);
    }
});

piFirstName.bind(Bindings.when(firstNameValidation).then(100).otherwise(0));

// similarly for other properties...

// then (this logic is equivalent to yours, but easier to read imho)

btnSetPermissions.disableProperty().bind(
    (firstNameValidation.and(middleNameValidation)
     .and(userNameValidation).and(passwordValidation)
     .and(retypePasswordValidation).and(emailValidation)
     .and(phoneNumberValidation)
    ).not());


注意,您当然可以通过以通常的方式将重复的内容移动到方法上来减少代码:

private BooleanBinding createValidationBinding(
        TextField field, Predicate<String> validationRule,
        StringProperty boundValue, ProgressIndicator indicator) {

    BooleanBinding validation = Bindings.createBooleanBinding(() -> {
        String value = field.getText();
        return validationRule.test(value);
    }, field.textProperty());

    field.textProperty().addListener((obs, oldText, newText) -> {
        if (binding.get()) {
            boundValue.set(newText);
        }
    });

    indicator.progressProperty().bind(Bindings.when(validation).then(100).otherwise(0));

    return validation ;
}


那你就可以

firstNameValidation = createValidationBinding(txtFirstName,
    name -> /* boolean indicating if name is valid */,
    employee.firstNameProperty(), piFirstName);


其他领域也是如此。

关于java - JavaFX Button的disableProperty绑定(bind)到多个BooleanBindings,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43905169/

10-13 04:31