Как объединить несколько валидаторов ControlsFX для текстового поля? - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь проверить следующее из текстового поля: 1. Оно не пустое (имеет значение) 2. Является ли число (не каким-либо другим символом) 3. Имеет определенный min и max (диапазон)

Для этого я использую пустой валидатор, регулярное выражение и валидатор, соответственно, и объединяю их.Однако кажется, что он использует только последний валидатор в списке и игнорирует остальные.

Вот код:

private final Spinner<Integer> createSpinner(ValueRange range, int initialValue){
        int min = (int) range.getMinimum();
        int max = (int) range.getMaximum();

        //TODO add validation in here
        Spinner<Integer> spinner = new Spinner<Integer>();
        spinner.setPrefSize(30, 30);
        spinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL);
        spinner.setEditable(true);

        SpinnerValueFactory.IntegerSpinnerValueFactory valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(min, max, initialValue);
        valueFactory.setConverter(new TimeIntegerStringConverter());
        valueFactory.setWrapAround(true);
        spinner.setValueFactory(valueFactory);

        //validation
        TextField editor = spinner.getEditor();
        validationSupport.registerValidator(editor, false, Validator.<String>combine(
                Validator.createEmptyValidator("Field cannot be empty",Severity.WARNING),
                checkInRangeValidator(range),
                checkIntegerValidator()
                ));

        return spinner;
    }

private static Validator<String> checkInRangeValidator(ValueRange range) {
        String message = String.format("Input value must be between [%d,%d]", (int) range.getMinimum(), (int) range.getMaximum());
        return Validator.<String>createPredicateValidator(
                s ->   range.isValidIntValue(Integer.valueOf(s)),
                message,
                Severity.ERROR
                );
    }

    private static Validator<String> checkIntegerValidator(){
        String message = "Input must be a number";
        return Validator.createRegexValidator(message, "\\d+", Severity.ERROR);

    }

Я не уверен, почему валидаторы не объединяются.Если я добавлю их отдельно в функции объединения, каждый валидатор будет работать.Но вместе они этого не делают.

1 Ответ

0 голосов
/ 17 октября 2018
validationSupport.registerValidator(editor, false, Validator.<String>combine(
                emptyValidator,
                twoDigitValidator,
                new RangeValidator(range)
                ));


private final Validator<String> emptyValidator = (control,value) ->
             ValidationResult.fromErrorIf(control, "Value cannot be empty", StringExtended.isEmptyOrNullOrWhitespace(value));


    private final Validator<String> twoDigitValidator = (control,value) -> {
            return ValidationResult.fromErrorIf(control, "Value must consist of 2 digits", !value.matches("\\d{2}"));

    };

    private class RangeValidator implements Validator<String>{

        private ValueRange range;

        RangeValidator(ValueRange range){
            this.range = range;
        }

        @Override
        public ValidationResult apply(Control control, String value) {
            String message = String.format("Input value must be between [%d,%d]", (int) range.getMinimum(), (int) range.getMaximum());
            return ValidationResult.fromErrorIf(control, message,  !range.isValidIntValue(Integer.valueOf(value)));
        }

    }
...