/* * Copyright (c) 2002-2015, JIDE Software Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package jidefx.scene.control.validation; import javafx.geometry.Insets; import javafx.geometry.Point2D; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Cell; import javafx.scene.control.Label; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import jidefx.animation.AnimationType; import jidefx.animation.AnimationUtils; import jidefx.scene.control.decoration.DecorationUtils; import jidefx.scene.control.decoration.Decorator; import java.util.Arrays; import java.util.function.Function; public class ValidationDecorators { private static final Double DEFAULT_TOOLTIP_OFFSET_X = 15.0; private static final Double DEFAULT_TOOLTIP_OFFSET_Y = 15.0; public static final String PROPERTY_VALIDATION_DECORATOR = "validation-decorator"; //NON-NLS public static final String PROPERTY_REQUIRED_VALIDATION_DECORATOR = "required-validation-decorator"; //NON-NLS public static Decorator<Label> graphicDecoratorCreator(Node targetNode, Decorator oldDecorator, ValidationEvent event) { Label label; ImageView graphic = new ImageView(ValidationIcons.getInstance().getValidationResultIcon(event.getEventType())); if (oldDecorator != null && exists(targetNode, oldDecorator)) { label = (Label) oldDecorator.getNode(); label.setGraphic(graphic); label.setTooltip(createTooltip(event.getMessage(), label)); DecorationUtils.setAnimationPlayed(label, false); return oldDecorator; } else { return createAndInstallValidationDecorator(targetNode, event, ValidationDecorationType.GRAPHIC); } } public static Decorator<Label> fontAwesomeDecoratorCreator(Node targetNode, Decorator oldDecorator, ValidationEvent event) { Label label; String fontAwesomeIcon = ValidationFontAwesomeIcons.getInstance().getValidationFontAwesomeIcon(event.getEventType()); if (oldDecorator != null && exists(targetNode, oldDecorator)) { label = (Label) oldDecorator.getNode(); label.setText(fontAwesomeIcon); label.setTooltip(createTooltip(event.getMessage(), label)); DecorationUtils.setAnimationPlayed(label, false); return oldDecorator; } else { return createAndInstallValidationDecorator(targetNode, event, ValidationDecorationType.FONT_AWESOME); } } public static void defaultDecorationClickBehavior(MouseEvent mouseEvent) { if (mouseEvent.getTarget() != null && mouseEvent.getTarget() instanceof Label) { Label label = (Label) mouseEvent.getTarget(); if (label.getTooltip() != null) { Point2D point = label.localToScene(DEFAULT_TOOLTIP_OFFSET_X, DEFAULT_TOOLTIP_OFFSET_Y); label.getTooltip().setAutoHide(true); label.getTooltip().show(label, point.getX() + label.getScene().getX() + label.getScene().getWindow().getX(), point.getY() + label.getScene().getY() + label.getScene().getWindow().getY()); } } } public static boolean exists(Node targetNode, Decorator resultDecorator) { Object o = DecorationUtils.getDecorators(targetNode); if (o != null) { if (o.equals(resultDecorator) || (o instanceof Decorator[] && Arrays.asList((Decorator[]) o).contains(resultDecorator))) { return true; } } return false; } public static ValidationUtils.TooltipFix createTooltip(String message, Label label) { ValidationUtils.TooltipFix tooltip = null; if (message != null && message.trim().length() > 0) { tooltip = new ValidationUtils.TooltipFix(label); tooltip.setText(message); tooltip.setAutoHide(true); tooltip.setConsumeAutoHidingEvents(false); } return tooltip; } public static Decorator<Label> createAndInstallValidationDecorator(Node targetNode, ValidationEvent event, ValidationDecorationType type) { Label label = new Label(); label.getStyleClass().add(PROPERTY_VALIDATION_DECORATOR); label.setTooltip(createTooltip(event.getMessage(), label)); switch (type) { case GRAPHIC: label.setGraphic(new ImageView(ValidationIcons.getInstance().getValidationResultIcon(event.getEventType()))); break; case FONT_AWESOME: label.setText(ValidationFontAwesomeIcons.getInstance().getValidationFontAwesomeIcon(event.getEventType())); label.setStyle("-fx-font-family: FontAwesome;"); break; } label.addEventHandler(MouseEvent.MOUSE_CLICKED, ValidationDecorators::defaultDecorationClickBehavior); Decorator<Label> newDecorator = null; if (targetNode instanceof Cell) { newDecorator = new Decorator<>(label, Pos.CENTER_RIGHT, new Point2D(-60, 0), new Insets(0, 100, 0, 0), AnimationType.TADA); } else { newDecorator = new Decorator<>(label, Pos.BOTTOM_LEFT, new Point2D(0, 0), new Insets(0, 0, 0, 0), AnimationType.TADA); } DecorationUtils.install(targetNode, newDecorator); targetNode.getParent().requestLayout(); return newDecorator; } public static Decorator<Label> graphicRequiredCreator(Node targetNode) { Image image = new Image(ValidationIcons.ICON_REQUIRED); Label lblRequired = new Label("", new ImageView(image)); lblRequired.getStyleClass().add(PROPERTY_REQUIRED_VALIDATION_DECORATOR); Decorator<Label> requiredDecorator = new Decorator<>(lblRequired, Pos.TOP_LEFT, new Point2D(image.getWidth()/2, image.getHeight()/2), new Insets(0, 0, 0, 0), false, AnimationUtils.createTransition(targetNode, AnimationType.NONE)); return requiredDecorator; } public static Decorator<Label> fontAwesomeRequiredCreator(Node targetNode) { Label lblRequired = new Label(); lblRequired.setText("\uf005"); lblRequired.setStyle("-fx-font-family: FontAwesome;"); lblRequired.getStyleClass().add(PROPERTY_REQUIRED_VALIDATION_DECORATOR); Decorator<Label> requiredDecorator = new Decorator<>(lblRequired, Pos.TOP_LEFT, new Point2D(0, 0), new Insets(0, 0, 0, 0)); return requiredDecorator; } public static Decorator<Label> installRequiredDecorator(Node targetNode, Function<Node, Decorator<Label>> requiredDecoratorCreator) { Decorator<Label> decorator = requiredDecoratorCreator.apply(targetNode); DecorationUtils.install(targetNode, decorator); targetNode.getParent().requestLayout(); return decorator; } }