[JAVA] Use ControlsFX / Validation

environment

Validation in ControlsFX

Let's use the validation function of ControlsFX to implement the input check function in a JavaFX application. It looks like the following.

0.png

Hover over the error icon to see an error message in a tooltip. (It feels a little hard to notice)

0e.png

Preparation

Since ControlsFX is used, add ControlsFX to the dependency of Gradle or Maven. If you want to import directly, please download from here.

Validator Validator provides a basic mechanism for checking the input contents, and you can also define the conditions yourself. You can create a validator using the following four methods.

Validator<T>:: motion
createEmptyValicator Set blank input to ERROR
createEqualsValidator Make input not in the list ERROR
createRegexValidator Set ERROR for input that does not match the regular expression
createPredicateValidator Specified Predicate<S>Set the input that does not match to ERROR

Predicate <S> is a functional interface that takes a ** control value ** and returns a boolean. You can implement your favorite conditions using lambda expressions, so you can write clearly and it is useful. Also, specify the error level (Severity.ERROR or Severity.WARNING) and error message in the argument. Validator (ControlsFX): API Document

To set multiple validators in one control, you need to use Validator <T> :: combine to synthesize the validators, but I won't cover them here. (There is also a way to do it with just one, such as using "Please enter in the format of" as an empty check.)

A code example of validation is given below.

ValidationSupport Valicator is used by registering it in the ValidationSupport class. After that, validation is done automatically every time the input contents are changed, so all validation works only with the following example.

Use ValidationSupport :: registerValidator to register the validator. You can specify whether to display the required icon when registering.

In initialize etc.


ValidationSupport support = new ValidationSupport();
support.registerValidator(textField1, false, Validator.createEmptyValidator(
                "Text is required",
                Severity.WARNING));
support.registerValidator(textField2, Validator.createEqualsValidator(
                "A or B or C is required",
                Arrays.asList("A", "B", "C")));
support.registerValidator(textField3, Validator.createRegexValidator(
                "Number is required",
                Pattern.compile("^[0-9]+$"), Severity.ERROR));
support.registerValidator(checkBox, Validator.createEqualsValidator(
                "Check is required",
                Collections.singletonList(true)));
support.registerValidator(comboBox, Validator.createEqualsValidator(
                "First item is required",
                Collections.singletonList(comboBox.getItems().get(0))));
support.registerValidator(colorPicker, Validator.createEqualsValidator(
                "WHITE or BLACK is required",
                Arrays.asList(Color.WHITE, Color.BLACK)));
support.registerValidator(slider, Validator.createPredicateValidator(
                (Double value) ->  value > 0.0,
                "Positive number is required"));

//Using static import
// import static org.controlsfx.validation.Validator.*;
//Then every time Validator.You don't have to write

5.png

The ValidationSupport class has properties for the entire validation result, which is useful for implementing a mechanism to follow the entire result.

//Buttons that are valid only if all results are valid
Button buttonValidated= new Button();
buttonValidated.disableProperty().bind(support.invalidProperty());

//ListView to display all error messages
ListView<ValidationMessage> listView = new ListView<>();
support.validationResultProperty().addListener((o, oldValue, newValue) ->
                listView.getItems().setAll(newValue.getMessages()));

ValidationSupport (ControlsFX): API Document

If you want to change the error display by CSS

The above example only displays the error with the default icon, but you can change this. Using StyleClassValidateionDecoration will add a style class to the control, warning for warnings and ʻerrorfor errors. The implementer needs to describe the error style in the CSS file applied toScene`. It can also be used in combination with the icon display.

//For CSS only
support.setValidationDecorator(new StyleClassValidationDecoration());
//When using icon and CSS together
support.setValidationDecorator(new CompoundValidationDecoration(
    new GraphicValidationDecoration(), 
    new StyleClassValidationDecoration()));

Main.css


.warning{
    -fx-border-color: orange;
    -fx-border-width: 2;
}
.error{
    -fx-border-color: red;
    -fx-border-width: 2;
}

Where to read FXML etc.


scene.getStylesheets().addAll(getClass().getResource("Main.css").toExternalForm());

The following is the screen display when using the icon and CSS together.

5e.png

In the case of CSS only, there is no way to display the tooltip, so it is necessary to devise to convey the error content.

If you want to redesign icons and tooltips

Icon and tooltip redesigns can be done by inheriting GraphicValidationDecoration and overriding the corresponding methods.

GraphicValidationDecoration:: Description
createErrorNode Error icon
createWarningNode Warning icon
createRequireDecorations Required icon
createTooltip Tooltip

I think it would be easier to rewrite a part of it with reference to the original source. GraphicValidationDecoration (ControlsFX): API Document bitbucket: GraphicValidationDecoration

Code that sets the inherited class


support.setValidationDecorator(new YourGraphicValidationDecoration());

Precautions when validating custom controls

The ControlsFX validator doesn't know which property of the custom control you created should be checked. If you want to validate a non-JavaFX standard control, you need to teach it with the following code. Click here for official explanation

//When you want to validate the value of some property for YourControl control
ValueExtractor.addObservableValueExtractor( 
        c -> c instanceof YourControl, 
        c -> ((YourControl)c).someProperty());

reference

ControlsFX: sample Source: GIT FXML,CSS: GIT

Recommended Posts

Use ControlsFX / Validation
[Rails] How to use validation
Use before_action! !!
Use XMLHttpRequest
[Rails] Use validation on a specific controller
Use ActiveStorage!
Use AutosizingTextView