improved side bar popup

This commit is contained in:
Andreas Billmann
2016-01-27 09:59:12 +01:00
parent 26c06a0908
commit ef1ad63b3f
2 changed files with 49 additions and 17 deletions

View File

@@ -31,18 +31,20 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.collections.WeakListChangeListener; import javafx.collections.WeakListChangeListener;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext; import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.util.Duration;
import ninja.javafx.smartcsv.fx.table.model.CSVModel; import ninja.javafx.smartcsv.fx.table.model.CSVModel;
import ninja.javafx.smartcsv.validation.ValidationError; import ninja.javafx.smartcsv.validation.ValidationError;
import org.controlsfx.control.PopOver; import org.controlsfx.control.PopOver;
import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@@ -54,13 +56,16 @@ import static ninja.javafx.smartcsv.fx.util.I18nValidationUtil.getI18nValidatioM
*/ */
public class ErrorSideBar extends Pane { public class ErrorSideBar extends Pane {
private static final double WIDTH = 20.0;
private static final int BLOCKSIZE = 6;
private ListChangeListener<ValidationError> errorListListener = c -> requestLayout(); private ListChangeListener<ValidationError> errorListListener = c -> requestLayout();
private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener); private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener);
private ObjectProperty<CSVModel> model = new SimpleObjectProperty<>(); private ObjectProperty<CSVModel> model = new SimpleObjectProperty<>();
private Canvas canvas = new Canvas(); private Canvas canvas = new Canvas();
private ObjectProperty<ValidationError> selectedValidationError = new SimpleObjectProperty<>(); private ObjectProperty<ValidationError> selectedValidationError = new SimpleObjectProperty<>();
private PopOver popOver = new PopOver(); private PopOver popOver = new PopOver();
private static final double WIDTH = 20.0; private List<ValidationError> lastPopupErrors = null;
public ErrorSideBar(ResourceBundle resourceBundle) { public ErrorSideBar(ResourceBundle resourceBundle) {
getChildren().add(canvas); getChildren().add(canvas);
@@ -96,19 +101,8 @@ public class ErrorSideBar extends Pane {
} }
private void addOnMouseOverListenerForPopOver(ResourceBundle resourceBundle) { private void addOnMouseOverListenerForPopOver(ResourceBundle resourceBundle) {
setOnMouseMoved(event -> { setOnMouseMoved(event -> showPopOver(event, resourceBundle));
List<ValidationError> errors = findValidationErrors(event.getY()); setOnMouseEntered(event -> showPopOver(event, resourceBundle));
if (!errors.isEmpty()) {
StringWriter messages = new StringWriter();
for (ValidationError validationError: errors) {
messages.append(getI18nValidatioMessage(resourceBundle, validationError)).append("\n");
}
popOver.setContentNode(popupContent(messages.toString()));
popOver.show(ErrorSideBar.this.getParent(), event.getScreenX()-WIDTH, event.getScreenY());
} else {
popOver.hide();
}
});
} }
private void addMouseClickListener() { private void addMouseClickListener() {
@@ -127,6 +121,24 @@ public class ErrorSideBar extends Pane {
}); });
} }
private void showPopOver(MouseEvent event, ResourceBundle resourceBundle) {
List<ValidationError> 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<ValidationError> errors) {
return lastPopupErrors != null && lastPopupErrors.size() == errors.size() && lastPopupErrors.containsAll(errors);
}
private void configurePopOver() { private void configurePopOver() {
popOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_CENTER); popOver.setArrowLocation(PopOver.ArrowLocation.RIGHT_CENTER);
} }
@@ -163,7 +175,7 @@ public class ErrorSideBar extends Pane {
double space = ((int)canvas.getHeight()) / rows; double space = ((int)canvas.getHeight()) / rows;
for (ValidationError error : errorList) { for (ValidationError error : errorList) {
double blockStart = space * error.getLineNumber(); double blockStart = space * error.getLineNumber();
if (blockStart-1 <= y && y <= blockStart+3) { if (blockStart - 1 <= y && y <= blockStart + BLOCKSIZE + 1) {
errors.add(error); errors.add(error);
} }
} }
@@ -185,8 +197,13 @@ public class ErrorSideBar extends Pane {
double space = h / rows; double space = h / rows;
for (ValidationError error : errorList) { for (ValidationError error : errorList) {
double blockStart = space * error.getLineNumber(); double blockStart = space * error.getLineNumber();
g.fillRect(0, blockStart, w, 2); g.fillRect(0, blockStart, w, BLOCKSIZE - 2);
} }
for (ValidationError error : errorList) {
double blockStart = space * error.getLineNumber();
g.clearRect(0, blockStart + BLOCKSIZE + 1, w, 1);
}
} }
} }
} }
@@ -196,6 +213,7 @@ public class ErrorSideBar extends Pane {
VBox vBox = new VBox(); VBox vBox = new VBox();
vBox.setPadding(new Insets(10,10,10,10)); vBox.setPadding(new Insets(10,10,10,10));
vBox.getChildren().add(new Text(text)); vBox.getChildren().add(new Text(text));
vBox.setAlignment(Pos.CENTER);
return vBox; return vBox;
} }
} }

View File

@@ -40,6 +40,20 @@ import static java.text.MessageFormat.format;
*/ */
public class I18nValidationUtil { public class I18nValidationUtil {
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, List<ValidationError> errors) {
StringWriter message = new StringWriter();
for (ValidationError validationError: errors) {
message.append(getI18nValidatioMessage(resourceBundle, validationError)).append("\n");
}
if (message.toString().length() != 0) {
return cutOffLastLineBreak(message.toString());
}
return "";
}
public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) { public static String getI18nValidatioMessage(ResourceBundle resourceBundle, ValidationError error) {
List<ValidationMessage> validationMessages = error.getMessages(); List<ValidationMessage> validationMessages = error.getMessages();