Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#600 make ValidationVisualizerBase methods protected #602

Merged
merged 2 commits into from
Oct 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: java
dist: trusty

sudo: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@
* this visualization you have to add the ControlsFX library to your classpath, otherwise you will get
* {@link NoClassDefFoundError}s and {@link ClassNotFoundException}s. If you are using a build management system like
* <i>maven</i> or <i>gradle</i> you simply have to add the library as dependency.
*
*
*
*
* @author manuel.mauky
*/
public class ControlsFxVisualizer extends ValidationVisualizerBase {

private ValidationDecoration decoration = new GraphicValidationDecoration();

/**
* Define a custom ControlsFX {@link ValidationVisualizer} that is used to visualize the validation results.
* <p>
Expand All @@ -48,39 +48,39 @@ public class ControlsFxVisualizer extends ValidationVisualizerBase {
public void setDecoration(ValidationDecoration decoration) {
this.decoration = decoration;
}


@Override
void applyRequiredVisualization(Control control, boolean required) {
protected void applyRequiredVisualization(Control control, boolean required) {
ValidationSupport.setRequired(control, required);
if (required) {
decoration.applyRequiredDecoration(control);
}
}

@Override
void applyVisualization(Control control, Optional<ValidationMessage> messageOptional, boolean required) {
protected void applyVisualization(Control control, Optional<ValidationMessage> messageOptional, boolean required) {

if (messageOptional.isPresent()) {
final ValidationMessage message = messageOptional.get();

decoration.removeDecorations(control);

if (Severity.ERROR.equals(message.getSeverity())) {
decoration.applyValidationDecoration(org.controlsfx.validation.ValidationMessage.error(control,
message.getMessage()));
} else if (Severity.WARNING.equals(message.getSeverity())) {
decoration.applyValidationDecoration(org.controlsfx.validation.ValidationMessage.warning(control,
message.getMessage()));
}

} else {
decoration.removeDecorations(control);
}

if (required) {
decoration.applyRequiredDecoration(control);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
* <p>
* This base class takes care for the handling of the {@link ValidationStatus} and the reaction to it's changing message
* lists.
*
*
* @author manuel.mauky
*/
public abstract class ValidationVisualizerBase implements ValidationVisualizer {


@Override
public void initVisualization(final ValidationStatus result, final Control control, boolean required) {
Platform.runLater(() -> {
Expand All @@ -56,19 +56,19 @@ public void initVisualization(final ValidationStatus result, final Control contr
});
});
}

/**
* Apply a visualization to the given control that indicates that it is a mandatory field.
* <p>
* This method is called when the validator is initialized.
*
*
* @param control
* the controls that has to be decorated.
* @param required
* a boolean indicating whether the given control is mandatory or not.
*/
abstract void applyRequiredVisualization(Control control, boolean required);
protected abstract void applyRequiredVisualization(Control control, boolean required);

/**
* Apply a visualization to the given control that shows a validation message.
* <p>
Expand All @@ -81,8 +81,8 @@ public void initVisualization(final ValidationStatus result, final Control contr
* <p>
* The given boolean parameter indicates whether this controls is mandatory or not. It can be used if a violation
* for a mandatory field should be visualized differently than a non-mandatory field.
*
*
*
*
* @param control
* the control that will be decorated.
* @param messageOptional
Expand All @@ -91,6 +91,6 @@ public void initVisualization(final ValidationStatus result, final Control contr
* @param required
* a boolean flag indicating whether this control is mandatory or not.
*/
abstract void applyVisualization(Control control, Optional<ValidationMessage> messageOptional, boolean required);
protected abstract void applyVisualization(Control control, Optional<ValidationMessage> messageOptional, boolean required);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.saxsys.mvvmfx.utils.validation.cssvisualizer;

import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
import de.saxsys.mvvmfx.utils.validation.visualization.ValidationVisualizerBase;

import java.util.List;
import java.util.Optional;

import javafx.scene.control.Control;

public class CssVisualizer extends ValidationVisualizerBase {

private final String errorStyleClass;
private final String validStyleClass;
private final String requiredStyleClass;

public CssVisualizer(String errorStyleClass, String validStyleClass, String requiredStyleClass) {
this.errorStyleClass = errorStyleClass;
this.validStyleClass = validStyleClass;
this.requiredStyleClass = requiredStyleClass;
}

@Override
protected void applyRequiredVisualization(Control control, boolean required) {
addIfAbsent(control.getStyleClass(), requiredStyleClass);
}

@Override
public void applyVisualization(Control control, Optional<ValidationMessage> messageOptional, boolean required) {
if (messageOptional.isPresent()) {
control.getStyleClass().remove(validStyleClass);
addIfAbsent(control.getStyleClass(), errorStyleClass);
} else {
control.getStyleClass().remove(errorStyleClass);
addIfAbsent(control.getStyleClass(), validStyleClass);
}
}

private static <T> void addIfAbsent(List<T> list, T element) {
if (!list.contains(element)) {
list.add(element);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package de.saxsys.mvvmfx.utils.validation.cssvisualizer;

import de.saxsys.mvvmfx.FluentViewLoader;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class CssVisualizerExampleApp extends Application {

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {

Parent parent = FluentViewLoader.fxmlView(CssVisualizerView.class).load().getView();

primaryStage.setScene(new Scene(parent));
primaryStage.show();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package de.saxsys.mvvmfx.utils.validation.cssvisualizer;

import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.InjectViewModel;
import de.saxsys.mvvmfx.utils.validation.visualization.ValidationVisualizer;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;

public class CssVisualizerView implements FxmlView<CssVisualizerViewModel> {

@FXML
private TextField email;

@InjectViewModel
private CssVisualizerViewModel viewModel;

private ValidationVisualizer visualizer = new CssVisualizer("error", "valid", "required");

public void initialize() {
email.textProperty().bindBidirectional(viewModel.emailAddressProperty());

visualizer.initVisualization(viewModel.getValidationStatus(), email, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package de.saxsys.mvvmfx.utils.validation.cssvisualizer;

import de.saxsys.mvvmfx.ViewModel;
import de.saxsys.mvvmfx.utils.validation.FunctionBasedValidator;
import de.saxsys.mvvmfx.utils.validation.ValidationMessage;
import de.saxsys.mvvmfx.utils.validation.ValidationStatus;
import de.saxsys.mvvmfx.utils.validation.Validator;

import java.util.function.Function;
import java.util.regex.Pattern;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class CssVisualizerViewModel implements ViewModel {
private static final Pattern EMAIL_REGEX = Pattern
.compile("^$|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}");

private StringProperty emailAddress = new SimpleStringProperty("");

private Validator validator = new FunctionBasedValidator<String>(emailAddress, input -> {
if (input == null || input.trim().isEmpty() || !EMAIL_REGEX.matcher(input).matches()) {
return ValidationMessage.error("Invalid EMail address");
} else {
return null;
}
});

public ValidationStatus getValidationStatus() {
return validator.getValidationStatus();
}

public StringProperty emailAddressProperty() {
return emailAddress;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* This package contains an example for a simple custom visualizer that uses CSS styling. It's not intended to be an
* official visualizer but just a starting point for people to implement their own visualizers.
*/
package de.saxsys.mvvmfx.utils.validation.cssvisualizer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.VBox?>


<VBox stylesheets="@style.css" spacing="10.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.saxsys.mvvmfx.utils.validation.cssvisualizer.CssVisualizerView">

<children>
<Label text="Email:" />
<TextField fx:id="email" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

.error {
-fx-border-color: red;
}

.valid {
-fx-border-color: green;
}

.required {
-fx-background-color: yellow;
}