From 4c9f468e083e842e2ec554978f8369f29922c3f5 Mon Sep 17 00:00:00 2001 From: Andreas Billmann Date: Wed, 27 Jan 2016 23:11:39 +0100 Subject: [PATCH] use regions instead of drawing into canvas. thx to Dirk Lemmermann --- .../javafx/smartcsv/fx/list/ErrorSideBar.java | 130 ++++-------------- 1 file changed, 28 insertions(+), 102 deletions(-) diff --git a/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java b/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java index 726e867..c3c4d63 100644 --- a/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java +++ b/src/main/java/ninja/javafx/smartcsv/fx/list/ErrorSideBar.java @@ -31,16 +31,10 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.collections.ListChangeListener; import javafx.collections.WeakListChangeListener; import javafx.geometry.Insets; -import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; import javafx.scene.text.Text; -import javafx.util.Duration; import ninja.javafx.smartcsv.fx.table.model.CSVModel; import ninja.javafx.smartcsv.validation.ValidationError; import org.controlsfx.control.PopOver; @@ -49,31 +43,30 @@ import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; +import static javafx.geometry.Pos.CENTER; import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioMessage; /** * clickable side bar with error markers */ -public class ErrorSideBar extends Pane { +public class ErrorSideBar extends Region { private static final double WIDTH = 20.0; - private static final int BLOCKSIZE = 6; - private ListChangeListener errorListListener = c -> requestLayout(); + private ListChangeListener errorListListener = c -> {setErrorMarker();}; private WeakListChangeListener weakErrorListListener = new WeakListChangeListener<>(errorListListener); private ObjectProperty model = new SimpleObjectProperty<>(); - private Canvas canvas = new Canvas(); private ObjectProperty selectedValidationError = new SimpleObjectProperty<>(); private PopOver popOver = new PopOver(); - private List lastPopupErrors = null; + private ResourceBundle resourceBundle; public ErrorSideBar(ResourceBundle resourceBundle) { - getChildren().add(canvas); + this.resourceBundle = resourceBundle; setFixWidth(); - configurePopOver(); addModelListener(); - addMouseClickListener(); - addOnMouseOverListenerForPopOver(resourceBundle); + popOver.setAutoHide(true); + popOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_CENTER); + } public void setModel(CSVModel model) { @@ -100,120 +93,53 @@ public class ErrorSideBar extends Pane { this.selectedValidationError.set(selectedValidationError); } - private void addOnMouseOverListenerForPopOver(ResourceBundle resourceBundle) { - setOnMouseMoved(event -> showPopOver(event, resourceBundle)); - setOnMouseEntered(event -> showPopOver(event, resourceBundle)); - } - - private void addMouseClickListener() { - setOnMouseClicked(event -> { - List errors = findValidationErrors(event.getY()); - if (!errors.isEmpty()) { - selectedValidationError.setValue(errors.get(0)); - } - }); - } - private void addModelListener() { model.addListener((observable, oldValue, newValue) -> { newValue.getValidationError().addListener(weakErrorListListener); - requestLayout(); + setErrorMarker(); }); } - private void showPopOver(MouseEvent event, ResourceBundle resourceBundle) { - List errors = findValidationErrors(event.getY()); - if (!errors.isEmpty()) { - if (!areErrorsAlreadyInPopup(errors)) { - lastPopupErrors = errors; - popOver.setContentNode(popupContent(getI18nValidatioMessage(resourceBundle, errors))); - popOver.show(ErrorSideBar.this.getParent(), event.getScreenX() - WIDTH, event.getScreenY()); - } - } else { - lastPopupErrors = null; - popOver.hide(Duration.millis(50)); - } - } - - private boolean areErrorsAlreadyInPopup(List errors) { - return lastPopupErrors != null && lastPopupErrors.size() == errors.size() && lastPopupErrors.containsAll(errors); - } - - private void configurePopOver() { - popOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_CENTER); - } - private void setFixWidth() { setMinWidth(WIDTH); setPrefWidth(WIDTH); setMaxWidth(WIDTH); } - @Override - protected void layoutChildren() { - int top = (int) snappedTopInset(); - int right = (int) snappedRightInset(); - int bottom = (int) snappedBottomInset(); - int left = (int) snappedLeftInset(); - int w = (int) getWidth() - left - right; - int h = (int) getHeight() - top - bottom; - canvas.setLayoutX(left); - canvas.setLayoutY(top); - if (w != canvas.getWidth() || h != canvas.getHeight()) { - canvas.setWidth(w); - canvas.setHeight(h); - } - drawErrorMarker(w, h); - } - - private List findValidationErrors(double y) { - List errors = new ArrayList<>(); + private void setErrorMarker() { + List errorMarkerList = new ArrayList<>(); if (model.get() != null) { List errorList = model.get().getValidationError(); if (errorList != null && !errorList.isEmpty()) { int rows = model.get().getRows().size(); - double space = ((int)canvas.getHeight()) / rows; + double space = ((int)getHeight()) / rows; for (ValidationError error : errorList) { - double blockStart = space * error.getLineNumber(); - if (blockStart - 1 <= y && y <= blockStart + BLOCKSIZE + 1) { - errors.add(error); - } + errorMarkerList.add(generateErrorMarker(space, error)); } } } - return errors; + getChildren().setAll(errorMarkerList); } - private void drawErrorMarker(int w, int h) { - - GraphicsContext g = canvas.getGraphicsContext2D(); - g.clearRect(0, 0, w, h); - g.setFill(Color.valueOf("#ff8888")); - - if (model.get() != null) { - List errorList = model.get().getValidationError(); - if (errorList != null && !errorList.isEmpty()) { - int rows = model.get().getRows().size(); - double space = h / rows; - for (ValidationError error : errorList) { - double blockStart = space * error.getLineNumber(); - g.fillRect(0, blockStart, w, BLOCKSIZE - 2); - } - for (ValidationError error : errorList) { - double blockStart = space * error.getLineNumber(); - g.clearRect(0, blockStart + BLOCKSIZE + 1, w, 1); - } - - } - } + private Region generateErrorMarker(double space, ValidationError error) { + Region errorMarker = new Region(); + errorMarker.setLayoutY(space * error.getLineNumber()); + errorMarker.setPrefSize(WIDTH, 2); + errorMarker.setStyle("-fx-background-color: #ff8888"); + errorMarker.setOnMouseClicked(event -> selectedValidationError.setValue(error)); + errorMarker.setOnMouseEntered(event -> { + popOver.setContentNode(popupContent(getI18nValidatioMessage(resourceBundle, error))); + popOver.show(errorMarker, -16); + }); + return errorMarker; } - private Node popupContent(String text) { VBox vBox = new VBox(); vBox.setPadding(new Insets(10,10,10,10)); vBox.getChildren().add(new Text(text)); - vBox.setAlignment(Pos.CENTER); + vBox.setAlignment(CENTER); return vBox; } + }