mirror of
https://github.com/frosch95/SmartCSV.fx.git
synced 2026-04-11 13:38:23 +02:00
new feature: clickable error list
This commit is contained in:
@@ -32,27 +32,26 @@ import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import ninja.javafx.smartcsv.FileReader;
|
||||
import ninja.javafx.smartcsv.csv.CSVFileReader;
|
||||
import ninja.javafx.smartcsv.csv.CSVFileWriter;
|
||||
import ninja.javafx.smartcsv.fx.list.ValidationErrorListCell;
|
||||
import ninja.javafx.smartcsv.fx.table.ObservableMapValueFactory;
|
||||
import ninja.javafx.smartcsv.fx.table.ValidationCellFactory;
|
||||
import ninja.javafx.smartcsv.fx.table.model.CSVModel;
|
||||
import ninja.javafx.smartcsv.fx.table.model.CSVValue;
|
||||
import ninja.javafx.smartcsv.fx.table.model.CSVRow;
|
||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||
import ninja.javafx.smartcsv.validation.ValidationFileReader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
@@ -83,6 +82,12 @@ public class SmartCSVController extends FXMLController {
|
||||
@FXML
|
||||
private Label stateline;
|
||||
|
||||
@FXML
|
||||
private ListView errorList;
|
||||
|
||||
@FXML
|
||||
private AnchorPane tableWrapper;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// injections
|
||||
@@ -92,6 +97,7 @@ public class SmartCSVController extends FXMLController {
|
||||
private final LoadCSVService loadCSVService = new LoadCSVService();
|
||||
private final SaveCSVService saveCSVService = new SaveCSVService();
|
||||
private CSVModel model;
|
||||
private TableView<CSVRow> tableView;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -101,6 +107,10 @@ public class SmartCSVController extends FXMLController {
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
stateline.setVisible(false);
|
||||
errorList.setCellFactory(param -> new ValidationErrorListCell());
|
||||
errorList.getSelectionModel().selectedItemProperty().addListener(
|
||||
observable -> scrollToError()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +225,7 @@ public class SmartCSVController extends FXMLController {
|
||||
model = csvLoader.getData();
|
||||
model.setValidator(validationLoader.getValidator());
|
||||
|
||||
TableView<CSVRow> tableView = new TableView<>();
|
||||
tableView = new TableView<>();
|
||||
|
||||
for (String column: model.getHeader()) {
|
||||
addColumn(column, tableView);
|
||||
@@ -223,7 +233,14 @@ public class SmartCSVController extends FXMLController {
|
||||
tableView.getItems().setAll(model.getRows());
|
||||
tableView.setEditable(true);
|
||||
|
||||
applicationPane.setCenter(tableView);
|
||||
AnchorPane.setBottomAnchor(tableView, 0.0);
|
||||
AnchorPane.setTopAnchor(tableView, 0.0);
|
||||
AnchorPane.setLeftAnchor(tableView, 0.0);
|
||||
AnchorPane.setRightAnchor(tableView, 0.0);
|
||||
tableWrapper.getChildren().setAll(tableView);
|
||||
|
||||
|
||||
errorList.setItems(model.getValidationError());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,6 +265,17 @@ public class SmartCSVController extends FXMLController {
|
||||
tableView.getColumns().add(column);
|
||||
}
|
||||
|
||||
private void scrollToError() {
|
||||
ValidationError entry = (ValidationError)errorList.getSelectionModel().getSelectedItem();
|
||||
if (entry != null) {
|
||||
if (entry.getLineNumber() != null) {
|
||||
tableView.scrollTo(entry.getLineNumber());
|
||||
tableView.getSelectionModel().select(entry.getLineNumber());
|
||||
} else {
|
||||
tableView.scrollTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// inner class
|
||||
@@ -277,7 +305,7 @@ public class SmartCSVController extends FXMLController {
|
||||
try {
|
||||
fileReader.read(file);
|
||||
runLater(SmartCSVController.this::resetContent);
|
||||
} catch (IOException ex) {
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -300,7 +328,7 @@ public class SmartCSVController extends FXMLController {
|
||||
try {
|
||||
csvFileWriter.saveFile(model);
|
||||
runLater(SmartCSVController.this::resetContent);
|
||||
} catch (IOException ex) {
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2015 javafx.ninja <info@javafx.ninja>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
package ninja.javafx.smartcsv.fx.list;
|
||||
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.text.Text;
|
||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||
|
||||
/**
|
||||
* TODO: DESCRIPTION!!!
|
||||
*/
|
||||
public class ValidationErrorListCell extends ListCell<ValidationError> {
|
||||
|
||||
private Text text;
|
||||
|
||||
@Override
|
||||
public void updateItem(ValidationError validationError, boolean empty) {
|
||||
super.updateItem(validationError, empty);
|
||||
if (empty) {
|
||||
clearContent();
|
||||
} else {
|
||||
addContent(validationError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void clearContent() {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
|
||||
private void addContent(ValidationError validationError) {
|
||||
setText(null);
|
||||
text = new Text(validationError.getMessage());
|
||||
text.setWrappingWidth(180);
|
||||
setGraphic(text);
|
||||
}
|
||||
}
|
||||
@@ -64,12 +64,12 @@ public class EditableValidationCell extends TableCell<CSVRow, CSVValue> {
|
||||
protected void updateItem(CSVValue item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item == null || item.getValid().isValid() || isEditing()) {
|
||||
if (item == null || item.getValidationError() == null || isEditing()) {
|
||||
setStyle("");
|
||||
setTooltip(null);
|
||||
} else if (!item.getValid().isValid()) {
|
||||
} else if (item.getValidationError() != null) {
|
||||
setStyle("-fx-background-color: #ff8888");
|
||||
setTooltip(new Tooltip(item.getValid().error()));
|
||||
setTooltip(new Tooltip(item.getValidationError().getMessage()));
|
||||
}
|
||||
|
||||
if (item == null || empty) {
|
||||
|
||||
@@ -28,7 +28,7 @@ package ninja.javafx.smartcsv.fx.table.model;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import ninja.javafx.smartcsv.validation.ValidationState;
|
||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||
import ninja.javafx.smartcsv.validation.Validator;
|
||||
|
||||
/**
|
||||
@@ -41,6 +41,7 @@ public class CSVModel {
|
||||
private ObservableList<CSVRow> rows = FXCollections.observableArrayList();
|
||||
private String[] header;
|
||||
private String filepath;
|
||||
private ObservableList<ValidationError> validationError = FXCollections.observableArrayList();
|
||||
|
||||
public CSVModel(String filepath) {
|
||||
this.filepath = filepath;
|
||||
@@ -71,6 +72,10 @@ public class CSVModel {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public ObservableList<ValidationError> getValidationError() {
|
||||
return validationError;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a new and empty row
|
||||
* @return the new row
|
||||
@@ -105,22 +110,37 @@ public class CSVModel {
|
||||
* walks through the data and validates each value
|
||||
*/
|
||||
private void revalidate() {
|
||||
validationError.clear();
|
||||
|
||||
if (header != null && validator != null) {
|
||||
validator.isHeaderValid(header);
|
||||
addValidationError(validator.isHeaderValid(header));
|
||||
}
|
||||
|
||||
for (CSVRow row: rows) {
|
||||
for (int lineNumber = 0; lineNumber < rows.size(); lineNumber++) {
|
||||
CSVRow row = rows.get(lineNumber);
|
||||
row.setValidator(validator);
|
||||
for (String column: row.getColumns().keySet()) {
|
||||
CSVValue value = row.getColumns().get(column).getValue();
|
||||
value.setValidator(validator);
|
||||
if (validator != null) {
|
||||
value.setValid(validator.isValid(column, value.getValue()));
|
||||
ValidationError validationError = validator.isValid(column, value.getValue(), lineNumber);
|
||||
if (validationError != null) {
|
||||
addValidationError(validationError);
|
||||
value.setValidationError(validationError);
|
||||
} else {
|
||||
value.setValidationError(null);
|
||||
}
|
||||
} else {
|
||||
value.setValid(new ValidationState());
|
||||
value.setValidationError(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addValidationError(ValidationError validationError) {
|
||||
if (validationError != null) {
|
||||
this.validationError.add(validationError);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ package ninja.javafx.smartcsv.fx.table.model;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import ninja.javafx.smartcsv.validation.ValidationState;
|
||||
import ninja.javafx.smartcsv.validation.ValidationError;
|
||||
import ninja.javafx.smartcsv.validation.Validator;
|
||||
|
||||
/**
|
||||
@@ -41,7 +41,7 @@ public class CSVValue {
|
||||
private int rowNumber;
|
||||
private String column;
|
||||
private StringProperty value = new SimpleStringProperty();
|
||||
private ValidationState valid = new ValidationState();
|
||||
private ValidationError valid;
|
||||
|
||||
/**
|
||||
* single value of a cell
|
||||
@@ -89,7 +89,7 @@ public class CSVValue {
|
||||
*/
|
||||
public void setValue(String value) {
|
||||
if (validator != null) {
|
||||
valid = validator.isValid(column, value);
|
||||
valid = validator.isValid(column, value, rowNumber);
|
||||
}
|
||||
this.value.set(value);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ public class CSVValue {
|
||||
* returns if the value is valid to the rules of the validator
|
||||
* @return
|
||||
*/
|
||||
public ValidationState getValid() {
|
||||
public ValidationError getValidationError() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class CSVValue {
|
||||
* sets the state if a value is valid or not
|
||||
* @param valid the validation state
|
||||
*/
|
||||
protected void setValid(ValidationState valid) {
|
||||
protected void setValidationError(ValidationError valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user