All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.factoryfx.javafx.widget.validation.ValidationWidget Maven / Gradle / Ivy

package de.factoryfx.javafx.widget.validation;

import de.factoryfx.data.Data;
import de.factoryfx.data.util.LanguageText;
import de.factoryfx.data.validation.ValidationError;
import de.factoryfx.javafx.editor.data.DataEditor;
import de.factoryfx.javafx.util.UniformDesign;
import de.factoryfx.javafx.widget.Widget;
import javafx.beans.InvalidationListener;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.controlsfx.glyphfont.FontAwesome;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

public class ValidationWidget implements Widget {

    private LanguageText columnData=new LanguageText().en("data").de("Objekt");
    private LanguageText columnField=new LanguageText().en("field").de("Feld");
    private LanguageText columnValidation=new LanguageText().en("validation").de("Validierung");
    private LanguageText refresh=new LanguageText().en("refresh").de("Aktualisieren");
    private LanguageText noerror=new LanguageText().en("no errors found").de("Keine Fehler gefunden");

    private final Data root;
    private final UniformDesign uniformDesign;
    private final DataEditor dataEditor;

    public ValidationWidget(Data root, DataEditor dataEditor, UniformDesign uniformDesign){
        this.root = root;
        this.uniformDesign = uniformDesign;
        this.dataEditor = dataEditor;
    }

    private static class ValidationAndData{
        public final ValidationError validationError;
        public final Data data;
        public final String dataDisplayText;

        public ValidationAndData(ValidationError validationError, Data data, String dataDisplayText) {
            this.validationError = validationError;
            this.data = data;
            this.dataDisplayText = dataDisplayText;
        }
    }

    @Override
    public Node createContent() {
        final SplitPane splitPane = new SplitPane();
        splitPane.setOrientation(Orientation.VERTICAL);
        final TreeTableView tableView = new TreeTableView<>();
        tableView.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY);
        {
            final TreeTableColumn column = new TreeTableColumn<>(uniformDesign.getText(columnData));
            column.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().getValue().dataDisplayText));
            tableView.getColumns().add(column);
        }
        {
            final TreeTableColumn column = new TreeTableColumn<>(uniformDesign.getText(columnField));
            column.setCellValueFactory(param -> {
                String initialValue = "";
                if (param.getValue().getValue().validationError!=null){
                    initialValue = param.getValue().getValue().validationError.attributeDescription(uniformDesign.getLocale());
                }
                return new SimpleStringProperty(initialValue);
            });
            tableView.getColumns().add(column);
        }
        {
            final TreeTableColumn column = new TreeTableColumn<>(uniformDesign.getText(columnValidation));
            column.setCellValueFactory(param -> {
                String initialValue = "";
                if (param.getValue().getValue().validationError!=null){
                    initialValue = param.getValue().getValue().validationError.validationDescription(uniformDesign::getText);
                }
                return new SimpleStringProperty(initialValue);
            });
            tableView.getColumns().add(column);
        }


        tableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue!=null){
                dataEditor.edit(newValue.getValue().data);
                dataEditor.setHistory(newValue.getValue().data.internal().getPathFromRoot());
            } else {
                dataEditor.edit(null);
                dataEditor.resetHistory();
            }
        });

        VBox vBox = new VBox();
        VBox.setVgrow(tableView, Priority.ALWAYS);
        vBox.getChildren().add(tableView);
        final HBox buttons = new HBox();
        buttons.setPadding(new Insets(3));
        final Button refreshButton = new Button(uniformDesign.getText(refresh));
        uniformDesign.addIcon(refreshButton, FontAwesome.Glyph.REFRESH);
        refreshButton.setOnAction((a)->validate(tableView));
        buttons.getChildren().add(refreshButton);
        vBox.getChildren().add(buttons);

        validate(tableView);
        tableView.getRoot().setExpanded(true);

//        SplitPane.setResizableWithParent(vBox, Boolean.TRUE);
        splitPane.getItems().add(vBox);

        final ScrollPane scrollPane = new ScrollPane(dataEditor.createContent());
        scrollPane.setFitToWidth(true);
        scrollPane.setFitToHeight(true);
        splitPane.getItems().add(scrollPane);

        splitPane.disableProperty().bind(isValid);
        final BorderPane borderPane = new BorderPane();
        final InvalidationListener invalidationListener = observable -> {
            if (!isValid.get()) {
                borderPane.setCenter(splitPane);
            } else {
                final Label noErrorLabel = new Label(uniformDesign.getText(noerror));
                noErrorLabel.setGraphic(uniformDesign.createIconSuccess(FontAwesome.Glyph.CHECK));
                borderPane.setCenter(noErrorLabel);
            }
        };
        isValid.addListener(invalidationListener);
        invalidationListener.invalidated(isValid);
        return borderPane;
    }

    private void validate(TreeTableView tableView){
        final TreeItem root = new TreeItem<>();
        tableView.setRoot(root);
        tableView.setShowRoot(false);
        HashMap child2parent = this.root.internal().getChildToParentMap();

        List validationErrors= new ArrayList<>();
        for (Data data: this.root.internal().collectChildrenDeep()){
            TreeItem dataItem = new TreeItem<>();
            dataItem.setExpanded(true);
            data.internal().validateFlat().forEach(validationError->{
                validationErrors.add(validationError);
                TreeItem error =new TreeItem<>(new ValidationAndData(validationError,data,data.internal().getDisplayText()));
                dataItem.getChildren().add(error);
            });
            if (!dataItem.getChildren().isEmpty()){
                dataItem.setValue(new ValidationAndData(null,data,data.internal().getPathFromRoot(child2parent).stream().map(d->d.internal().getDisplayText()).collect(Collectors.joining("/"))));
                root.getChildren().add(dataItem);
            }
        }
        tableView.getStyleClass().remove("error");
        if (!validationErrors.isEmpty()){
            tableView.getStyleClass().add("error");
        }
        tableView.getSelectionModel().clearSelection();
        dataEditor.reset();
        isValid.set(validationErrors.isEmpty());
    }

    SimpleBooleanProperty isValid=new SimpleBooleanProperty();
    public ReadOnlyBooleanProperty isValid(){
        return isValid;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy