From 7310cd9ca6e728474ba2a5b051043def09985878 Mon Sep 17 00:00:00 2001 From: Vladimir Valekzhanin Date: Tue, 6 Oct 2026 11:24:35 +0300 Subject: [PATCH] feat: migrate validation from ValidatorFX to FormsFX --- pom.xml | 11 -- .../controllers/LoginFormController.java | 128 +++++++++--------- .../utils/FieldError.java | 28 ---- .../validation/EmailValidator.java | 27 ++-- .../validation/FirstNameValidator.java | 24 ++-- .../validation/LastNameValidator.java | 22 ++- .../validation/PasswordValidator.java | 23 ++-- .../validation/ThirdNameValidator.java | 20 +-- .../utils/FieldErrorDecoration.java | 26 ---- src/main/resources/fxml/LoginForm.fxml | 35 +---- .../java/validation/EmailValidatorTest.java | 43 +++--- .../validation/FirstNameValidatorTest.java | 37 ++--- .../validation/LastNameValidatorTest.java | 37 ++--- .../validation/PasswordValidatorTest.java | 45 +++--- .../validation/ThirdNameValidatorTest.java | 37 ++--- src/test/java/validation/ValidatorFxTest.java | 42 ------ 16 files changed, 231 insertions(+), 354 deletions(-) delete mode 100644 src/main/java/com/DesktopApplicationClientJava/utils/FieldError.java delete mode 100644 src/main/java/com/DesktopApplicationClientJava/validation/utils/FieldErrorDecoration.java delete mode 100644 src/test/java/validation/ValidatorFxTest.java diff --git a/pom.xml b/pom.xml index 77bd69e..a5bc40b 100644 --- a/pom.xml +++ b/pom.xml @@ -99,17 +99,6 @@ - - net.synedra - validatorfx - 0.6.1 - - - org.openjfx - * - - - org.kordamp.bootstrapfx bootstrapfx-core diff --git a/src/main/java/com/DesktopApplicationClientJava/controllers/LoginFormController.java b/src/main/java/com/DesktopApplicationClientJava/controllers/LoginFormController.java index da59504..c115ad5 100644 --- a/src/main/java/com/DesktopApplicationClientJava/controllers/LoginFormController.java +++ b/src/main/java/com/DesktopApplicationClientJava/controllers/LoginFormController.java @@ -3,88 +3,89 @@ import com.DesktopApplicationClientJava.controllers.utils.Controller; import com.DesktopApplicationClientJava.entities.Role; import com.DesktopApplicationClientJava.entities.User; -import com.DesktopApplicationClientJava.utils.FieldError; import com.DesktopApplicationClientJava.validation.EmailValidator; import com.DesktopApplicationClientJava.validation.FirstNameValidator; import com.DesktopApplicationClientJava.validation.LastNameValidator; import com.DesktopApplicationClientJava.validation.PasswordValidator; import com.DesktopApplicationClientJava.validation.ThirdNameValidator; -import com.DesktopApplicationClientJava.validation.utils.FieldErrorDecoration; +import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; +import com.dlsc.formsfx.model.structure.Field; +import com.dlsc.formsfx.model.structure.Form; +import com.dlsc.formsfx.model.structure.PasswordField; +import com.dlsc.formsfx.model.structure.Section; +import com.dlsc.formsfx.model.structure.StringField; +import com.dlsc.formsfx.model.validators.Validator; +import com.dlsc.formsfx.view.renderer.FormRenderer; +import java.util.List; import java.util.UUID; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.PasswordField; -import javafx.scene.control.TextField; -import net.synedra.validatorfx.Validator; +import javafx.scene.layout.VBox; public class LoginFormController extends Controller { - private final Validator validator = new Validator(); - - @FXML private TextField firstNameField; - @FXML private Label firstNameErrorLabel; - private FieldError firstNameError; - - @FXML private TextField lastNameField; - @FXML private Label lastNameErrorLabel; - private FieldError lastNameError; - - @FXML private TextField thirdNameField; - @FXML private Label thirdNameErrorLabel; - private FieldError thirdNameError; - - @FXML private TextField emailField; - @FXML private Label emailErrorLabel; - private FieldError emailError; - - @FXML private PasswordField passwordField; - @FXML private Label passwordErrorLabel; - private FieldError passwordError; - + @FXML private VBox formContainer; @FXML private Button submitButton; + private StringField firstName; + private StringField lastName; + private StringField thirdName; + private StringField email; + private PasswordField password; + private Form loginForm; + @FXML private void initialize() { - firstNameError = new FieldError(firstNameErrorLabel); - lastNameError = new FieldError(lastNameErrorLabel); - thirdNameError = new FieldError(thirdNameErrorLabel); - emailError = new FieldError(emailErrorLabel); - passwordError = new FieldError(passwordErrorLabel); - - setupValidation(); - } + firstName = + Field.ofStringType("") + .label(FirstNameValidator.FIELD_NAME) + .placeholder("Антон") + .required(ErrorMessages.Required) + .validate(toArray(FirstNameValidator.validators())); + lastName = + Field.ofStringType("") + .label(LastNameValidator.FIELD_NAME) + .placeholder("Антонов") + .required(ErrorMessages.Required) + .validate(toArray(LastNameValidator.validators())); + thirdName = + Field.ofStringType("") + .label(ThirdNameValidator.FIELD_NAME) + .placeholder("Антонович") + .required(ErrorMessages.Required) + .validate(toArray(ThirdNameValidator.validators())); + email = + Field.ofStringType("") + .label(EmailValidator.FIELD_NAME) + .placeholder("youremail@example.com") + .required(ErrorMessages.Required) + .validate(toArray(EmailValidator.validators())); + password = + Field.ofPasswordType("") + .label(PasswordValidator.FIELD_NAME) + .required(ErrorMessages.Required) + .validate(toArray(PasswordValidator.validators())); - private void setupValidation() { - FirstNameValidator.createCheck(validator, firstNameField.textProperty()) - .decoratingWith(FieldErrorDecoration.forError(firstNameError)) - .decorates(firstNameField) - .immediateClear(); - LastNameValidator.createCheck(validator, lastNameField.textProperty()) - .decoratingWith(FieldErrorDecoration.forError(lastNameError)) - .decorates(lastNameField) - .immediateClear(); - ThirdNameValidator.createCheck(validator, thirdNameField.textProperty()) - .decoratingWith(FieldErrorDecoration.forError(thirdNameError)) - .decorates(thirdNameField) - .immediateClear(); - EmailValidator.createCheck(validator, emailField.textProperty()) - .decoratingWith(FieldErrorDecoration.forError(emailError)) - .decorates(emailField) - .immediateClear(); - PasswordValidator.createCheck(validator, passwordField.textProperty()) - .decoratingWith(FieldErrorDecoration.forError(passwordError)) - .decorates(passwordField) - .immediateClear(); + loginForm = Form.of(Section.of(firstName, lastName, thirdName, email, password)); + formContainer.getChildren().add(new FormRenderer(loginForm)); } @FXML private void onSubmit(ActionEvent event) { - if (!validator.validate()) return; + boolean valid = + firstName.validate() + & lastName.validate() + & thirdName.validate() + & email.validate() + & password.validate(); + if (!valid) { + return; + } - User user = - authenticate(firstNameField.getText(), lastNameField.getText(), emailField.getText()); - if (user == null) return; + User user = authenticate(firstName.getValue(), lastName.getValue(), email.getValue()); + if (user == null) { + return; + } session.setCurrentUser(user); navigator.goTo("/fxml/Search.fxml"); @@ -93,4 +94,9 @@ private void onSubmit(ActionEvent event) { private User authenticate(String firstName, String lastName, String email) { return new User(UUID.randomUUID(), email, Role.USER, firstName, lastName, true); } + + @SuppressWarnings("unchecked") + private static Validator[] toArray(List> validators) { + return validators.toArray(new Validator[0]); + } } diff --git a/src/main/java/com/DesktopApplicationClientJava/utils/FieldError.java b/src/main/java/com/DesktopApplicationClientJava/utils/FieldError.java deleted file mode 100644 index cafa2bf..0000000 --- a/src/main/java/com/DesktopApplicationClientJava/utils/FieldError.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.DesktopApplicationClientJava.utils; - -import javafx.scene.control.Label; - -public class FieldError { - private final Label label; - - public FieldError(Label label) { - this.label = label; - } - - public void show(String message) { - if (label == null) return; - label.setText(message); - label.setVisible(true); - label.setManaged(true); - } - - public void hide() { - if (label == null) return; - label.setVisible(false); - label.setManaged(false); - } - - public boolean isShowing() { - return label.isVisible(); - } -} diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/EmailValidator.java b/src/main/java/com/DesktopApplicationClientJava/validation/EmailValidator.java index 8f0f4e0..d6f9a7c 100644 --- a/src/main/java/com/DesktopApplicationClientJava/validation/EmailValidator.java +++ b/src/main/java/com/DesktopApplicationClientJava/validation/EmailValidator.java @@ -2,15 +2,15 @@ import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; import com.DesktopApplicationClientJava.validation.utils.ValidatorHelpers; -import javafx.beans.value.ObservableValue; -import net.synedra.validatorfx.Check; -import net.synedra.validatorfx.Validator; +import com.dlsc.formsfx.model.validators.CustomValidator; +import com.dlsc.formsfx.model.validators.StringLengthValidator; +import com.dlsc.formsfx.model.validators.Validator; +import java.util.List; public final class EmailValidator { public static final String FIELD_NAME = "Почта"; public static final int MIN_EMAIL_LENGTH = 5; public static final int MAX_EMAIL_LENGTH = 100; - private static final String KEY = "value"; private EmailValidator() {} @@ -24,14 +24,19 @@ public static String validate(String input) { return null; } - public static void check(Check.Context context) { - String error = validate(context.get(KEY)); - if (error != null) { - context.error(error); - } + public static List> validators() { + return List.of( + CustomValidator.forPredicate( + input -> !ValidatorHelpers.isEmpty(input), ErrorMessages.Required), + StringLengthValidator.atLeast( + MIN_EMAIL_LENGTH, ErrorMessages.MinLength(FIELD_NAME, MIN_EMAIL_LENGTH)), + StringLengthValidator.upTo( + MAX_EMAIL_LENGTH, ErrorMessages.MaxLength(FIELD_NAME, MAX_EMAIL_LENGTH)), + CustomValidator.forPredicate( + EmailValidator::hasValidFormat, ErrorMessages.IncorrectFormat)); } - public static Check createCheck(Validator validator, ObservableValue property) { - return validator.createCheck().dependsOn(KEY, property).withMethod(EmailValidator::check); + private static boolean hasValidFormat(String input) { + return ValidatorHelpers.isEmpty(input) || ValidatorHelpers.includes(input, "@"); } } diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/FirstNameValidator.java b/src/main/java/com/DesktopApplicationClientJava/validation/FirstNameValidator.java index 78d78a3..2c125e1 100644 --- a/src/main/java/com/DesktopApplicationClientJava/validation/FirstNameValidator.java +++ b/src/main/java/com/DesktopApplicationClientJava/validation/FirstNameValidator.java @@ -2,14 +2,14 @@ import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; import com.DesktopApplicationClientJava.validation.utils.ValidatorHelpers; -import javafx.beans.value.ObservableValue; -import net.synedra.validatorfx.Check; -import net.synedra.validatorfx.Validator; +import com.dlsc.formsfx.model.validators.CustomValidator; +import com.dlsc.formsfx.model.validators.StringLengthValidator; +import com.dlsc.formsfx.model.validators.Validator; +import java.util.List; public final class FirstNameValidator { public static final String FIELD_NAME = "Имя"; - private static final int MIN_LENGTH = 2; - private static final String KEY = "value"; + public static final int MIN_LENGTH = 2; private FirstNameValidator() {} @@ -20,14 +20,10 @@ public static String validate(String input) { return null; } - public static void check(Check.Context context) { - String error = validate(context.get(KEY)); - if (error != null) { - context.error(error); - } - } - - public static Check createCheck(Validator validator, ObservableValue property) { - return validator.createCheck().dependsOn(KEY, property).withMethod(FirstNameValidator::check); + public static List> validators() { + return List.of( + CustomValidator.forPredicate( + input -> !ValidatorHelpers.isEmpty(input), ErrorMessages.Required), + StringLengthValidator.atLeast(MIN_LENGTH, ErrorMessages.MinLength(FIELD_NAME, MIN_LENGTH))); } } diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/LastNameValidator.java b/src/main/java/com/DesktopApplicationClientJava/validation/LastNameValidator.java index bd12ee7..a24c702 100644 --- a/src/main/java/com/DesktopApplicationClientJava/validation/LastNameValidator.java +++ b/src/main/java/com/DesktopApplicationClientJava/validation/LastNameValidator.java @@ -2,14 +2,14 @@ import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; import com.DesktopApplicationClientJava.validation.utils.ValidatorHelpers; -import javafx.beans.value.ObservableValue; -import net.synedra.validatorfx.Check; -import net.synedra.validatorfx.Validator; +import com.dlsc.formsfx.model.validators.CustomValidator; +import com.dlsc.formsfx.model.validators.StringLengthValidator; +import com.dlsc.formsfx.model.validators.Validator; +import java.util.List; public final class LastNameValidator { public static final String FIELD_NAME = "Фамилия"; public static final int MIN_LENGTH = 2; - private static final String KEY = "value"; private LastNameValidator() {} @@ -20,14 +20,10 @@ public static String validate(String input) { return null; } - public static Check createCheck(Validator validator, ObservableValue property) { - return validator.createCheck().dependsOn(KEY, property).withMethod(LastNameValidator::check); - } - - public static void check(Check.Context context) { - String error = validate(context.get(KEY)); - if (error != null) { - context.error(error); - } + public static List> validators() { + return List.of( + CustomValidator.forPredicate( + input -> !ValidatorHelpers.isEmpty(input), ErrorMessages.Required), + StringLengthValidator.atLeast(MIN_LENGTH, ErrorMessages.MinLength(FIELD_NAME, MIN_LENGTH))); } } diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/PasswordValidator.java b/src/main/java/com/DesktopApplicationClientJava/validation/PasswordValidator.java index 2dc0b09..1976007 100644 --- a/src/main/java/com/DesktopApplicationClientJava/validation/PasswordValidator.java +++ b/src/main/java/com/DesktopApplicationClientJava/validation/PasswordValidator.java @@ -2,15 +2,15 @@ import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; import com.DesktopApplicationClientJava.validation.utils.ValidatorHelpers; -import javafx.beans.value.ObservableValue; -import net.synedra.validatorfx.Check; -import net.synedra.validatorfx.Validator; +import com.dlsc.formsfx.model.validators.CustomValidator; +import com.dlsc.formsfx.model.validators.StringLengthValidator; +import com.dlsc.formsfx.model.validators.Validator; +import java.util.List; public final class PasswordValidator { public static final String FIELD_NAME = "Пароль"; public static final int MIN_LENGTH = 8; public static final int MAX_LENGTH = 64; - private static final String KEY = "value"; private PasswordValidator() {} @@ -23,14 +23,11 @@ public static String validate(String input) { return null; } - public static void check(Check.Context context) { - String error = validate(context.get(KEY)); - if (error != null) { - context.error(error); - } - } - - public static Check createCheck(Validator validator, ObservableValue property) { - return validator.createCheck().dependsOn(KEY, property).withMethod(PasswordValidator::check); + public static List> validators() { + return List.of( + CustomValidator.forPredicate( + input -> !ValidatorHelpers.isEmpty(input), ErrorMessages.Required), + StringLengthValidator.atLeast(MIN_LENGTH, ErrorMessages.MinLength(FIELD_NAME, MIN_LENGTH)), + StringLengthValidator.upTo(MAX_LENGTH, ErrorMessages.MaxLength(FIELD_NAME, MAX_LENGTH))); } } diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/ThirdNameValidator.java b/src/main/java/com/DesktopApplicationClientJava/validation/ThirdNameValidator.java index 5c429e0..0cca4f4 100644 --- a/src/main/java/com/DesktopApplicationClientJava/validation/ThirdNameValidator.java +++ b/src/main/java/com/DesktopApplicationClientJava/validation/ThirdNameValidator.java @@ -2,13 +2,12 @@ import com.DesktopApplicationClientJava.validation.utils.ErrorMessages; import com.DesktopApplicationClientJava.validation.utils.ValidatorHelpers; -import javafx.beans.value.ObservableValue; -import net.synedra.validatorfx.Check; -import net.synedra.validatorfx.Validator; +import com.dlsc.formsfx.model.validators.CustomValidator; +import com.dlsc.formsfx.model.validators.Validator; +import java.util.List; public final class ThirdNameValidator { public static final String FIELD_NAME = "Отчество"; - private static final String KEY = "value"; private ThirdNameValidator() {} @@ -17,14 +16,9 @@ public static String validate(String input) { return null; } - public static void check(Check.Context context) { - String error = validate(context.get(KEY)); - if (error != null) { - context.error(error); - } - } - - public static Check createCheck(Validator validator, ObservableValue property) { - return validator.createCheck().dependsOn(KEY, property).withMethod(ThirdNameValidator::check); + public static List> validators() { + return List.of( + CustomValidator.forPredicate( + input -> !ValidatorHelpers.isEmpty(input), ErrorMessages.Required)); } } diff --git a/src/main/java/com/DesktopApplicationClientJava/validation/utils/FieldErrorDecoration.java b/src/main/java/com/DesktopApplicationClientJava/validation/utils/FieldErrorDecoration.java deleted file mode 100644 index a39b93f..0000000 --- a/src/main/java/com/DesktopApplicationClientJava/validation/utils/FieldErrorDecoration.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.DesktopApplicationClientJava.validation.utils; - -import com.DesktopApplicationClientJava.utils.FieldError; -import java.util.function.Function; -import javafx.scene.Node; -import net.synedra.validatorfx.Decoration; -import net.synedra.validatorfx.ValidationMessage; - -public final class FieldErrorDecoration { - private FieldErrorDecoration() {} - - public static Function forError(FieldError error) { - return message -> - new Decoration() { - @Override - public void add(Node target) { - error.show(message.getText()); - } - - @Override - public void remove(Node target) { - error.hide(); - } - }; - } -} diff --git a/src/main/resources/fxml/LoginForm.fxml b/src/main/resources/fxml/LoginForm.fxml index 34fbb3c..2b86c50 100644 --- a/src/main/resources/fxml/LoginForm.fxml +++ b/src/main/resources/fxml/LoginForm.fxml @@ -2,9 +2,6 @@ - - - @@ -17,36 +14,8 @@