Validation 使用bindin进行验证

Validation 使用bindin进行验证,validation,javafx-2,fxml,Validation,Javafx 2,Fxml,我为JavaFX应用程序制作了一个配置面板。我成功地创建了一个动态更改侦听器,如下所示: public class InputMaskChecker implements ChangeListener<String> { public static final String NUMERIC = "^[0-9]*$"; public static final String TEXTONLY = "^\\w*$"; public static

我为JavaFX应用程序制作了一个配置面板。我成功地创建了一个动态更改侦听器,如下所示:

public class InputMaskChecker implements ChangeListener<String> {

    public static final String NUMERIC      = "^[0-9]*$";
    public static final String TEXTONLY     = "^\\w*$";
    public static final String PASSWORD     = "^[\\w\\+\\!\\?\\-\\$\\&\\%£]+$";
    public static final String DATASOURCE   = "^([a-zA-Z]+:){3}@([a-zA-Z0-9]+:)+[a-zA-Z0-9]+$";
    public static final String TCPPORT      = "^(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[2-9]\\d{3}|1[1-9]\\d{2}|10[3-9]\\d|102[4-9])$";

    private static final String STYLE = "-fx-effect: dropshadow(gaussian, red, 4, 0.0, 0, 0);";

    public final BooleanProperty erroneous = new SimpleBooleanProperty(false);

    private final String mask;
    private final int max_lenght;
    private final TextField control;


    public InputMaskChecker(String mask, TextField control) {
        this.mask = mask;
        this.max_lenght = 0;
        this.control = control;
    }

    public InputMaskChecker(String mask, int max_lenght, TextField control) {
        this.mask = mask;
        this.max_lenght = max_lenght;
        this.control = control;
    }

    @Override
    public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
        erroneous.setValue(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0);
        control.setStyle( erroneous.get() ? STYLE : "-fx-effect: null;");
    }
}
它的工作原理与预期一样,但有一个小故障:我希望主控制器上的“保存”按钮对侦听器做出反应,如果某个字段出现错误,它将被禁用

现在是我的头脑风暴请求。你有什么建议吗

使用共享的SimpleBoleAnProperty和ing侦听器显然不起作用

解决方案更新: 添加一个私有的最终布尔绑定;将变量添加到控制器。然后:

InputMaskChecker listener1 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field1);
InputMaskChecker listener2 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field2);
InputMaskChecker listener3 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field3);
InputMaskChecker listener4 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field4);

field1.textProperty().addListener(listener1);
field2.textProperty().addListener(listener2);
field3.textProperty().addListener(listener3);
field4.textProperty().addListener(listener4);

binding = new BooleanBinding() {
    {
    super.bind(listener1.erroneous, listener2.erroneous, listener3.erroneous, listener4.erroneous);
    }

    @Override
    protected boolean computeValue() {
        return (listener1.erroneous.get() || listener2.erroneous.get() || listener3.erroneous.get() || listener4.erroneous.get());
    }
};

control.getDisableProperty().bind(binding);

完成

我可以建议下一种方法:

使用公共SimpleBoleAnProperty使InputMaskChecker状态有效;将在更新方法中引用:

@Override
public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
    valid.set(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0);
    // BTW, I would suggest to use styleclasses instead for performance reasons
    control.setStyle( valid.get() ? STYLE : "-fx-effect: null; ):
}

或者创建一个实用程序方法,该方法将添加侦听器并更新Save disabled属性。

我可以建议下一种方法:

使用公共SimpleBoleAnProperty使InputMaskChecker状态有效;将在更新方法中引用:

@Override
public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
    valid.set(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0);
    // BTW, I would suggest to use styleclasses instead for performance reasons
    control.setStyle( valid.get() ? STYLE : "-fx-effect: null; ):
}

或者创建一个实用程序方法,该方法将添加侦听器并更新Save disabled属性。

通过低级绑定解决。无论如何,您不能将样式类与此一起使用。我尝试过,但是,一旦添加了一个styleclass,之后它就不会删除它…甚至使用.setEffectnew Dropshadow。。。;方法不起作用。唯一的机会是control.setStyle有效。获取?样式:-fx效果:null;setEffect预计不起作用。setStyle在样式命令链中具有最高优先级。当你们以另一种方式解决问题时,请将你们的代码作为一个单独的答案发布,并接受你们自己的答案而不是我的答案。好吧,这是另一个实现,但我遵循了你们的建议,你们的方式。无论如何,我会在将来记住这一点。感谢您的帮助和使用低级绑定解决的技巧。无论如何,您不能将样式类与此一起使用。我尝试过,但是,一旦添加了一个styleclass,之后它就不会删除它…甚至使用.setEffectnew Dropshadow。。。;方法不起作用。唯一的机会是control.setStyle有效。获取?样式:-fx效果:null;setEffect预计不起作用。setStyle在样式命令链中具有最高优先级。当你们以另一种方式解决问题时,请将你们的代码作为一个单独的答案发布,并接受你们自己的答案而不是我的答案。好吧,这是另一个实现,但我遵循了你们的建议,你们的方式。无论如何,我会在将来记住这一点。谢谢你的帮助和小费
Button btn = new Button("Save");
btn.disableProperty().bind(
      listener1.valid.and(listener2.valid).and(listener3.valid).not());