426 lines
14 KiB
Java
426 lines
14 KiB
Java
package ch.zhaw.gartenverwaltung;
|
|
|
|
import ch.zhaw.gartenverwaltung.bootstrap.AppLoader;
|
|
import ch.zhaw.gartenverwaltung.bootstrap.Inject;
|
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
|
import ch.zhaw.gartenverwaltung.io.TaskList;
|
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
|
import ch.zhaw.gartenverwaltung.types.Crop;
|
|
import ch.zhaw.gartenverwaltung.types.Pest;
|
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
|
import ch.zhaw.gartenverwaltung.types.Task;
|
|
import javafx.beans.property.ListProperty;
|
|
import javafx.beans.property.SimpleListProperty;
|
|
import javafx.collections.FXCollections;
|
|
import javafx.event.ActionEvent;
|
|
import javafx.event.EventHandler;
|
|
import javafx.fxml.FXML;
|
|
import javafx.geometry.Pos;
|
|
import javafx.scene.control.*;
|
|
import javafx.scene.image.Image;
|
|
import javafx.scene.image.ImageView;
|
|
import javafx.scene.layout.HBox;
|
|
import javafx.scene.layout.Pane;
|
|
import javafx.scene.layout.Priority;
|
|
import javafx.stage.Stage;
|
|
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* Controller class for the CropDetail.fxml file
|
|
*/
|
|
public class CropDetailController {
|
|
private Crop crop;
|
|
|
|
@Inject
|
|
private PlantList plantList;
|
|
@Inject
|
|
private GardenSchedule gardenSchedule;
|
|
@Inject
|
|
private Garden garden;
|
|
|
|
@Inject
|
|
AppLoader appLoader;
|
|
|
|
private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName());
|
|
private final ListProperty<Task> taskListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
private final ListProperty<Pest> pestListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
|
|
@FXML
|
|
private ImageView imageView;
|
|
|
|
@FXML
|
|
private Button area_button;
|
|
|
|
@FXML
|
|
private Label area_label;
|
|
|
|
@FXML
|
|
private Label cropName_label;
|
|
|
|
@FXML
|
|
private Label description_label;
|
|
|
|
@FXML
|
|
private Label light_label;
|
|
|
|
@FXML
|
|
private Label soil_label;
|
|
|
|
@FXML
|
|
private Label spacing_label;
|
|
|
|
@FXML
|
|
private Button addTask_button;
|
|
|
|
@FXML
|
|
private ListView<Task> taskList_listView;
|
|
|
|
@FXML
|
|
private ListView<Pest> pests_listView;
|
|
|
|
@FXML
|
|
void addTask() throws IOException, HardinessZoneNotSetException {
|
|
createTaskDialog(true, null);
|
|
}
|
|
|
|
/**
|
|
* close Window
|
|
*/
|
|
@FXML
|
|
void goBack() {
|
|
Stage stage = (Stage) imageView.getScene().getWindow();
|
|
stage.close();
|
|
}
|
|
|
|
/**
|
|
* open dialog to set area
|
|
*/
|
|
@FXML
|
|
void setArea() throws IOException {
|
|
openTextFieldDialog();
|
|
}
|
|
|
|
/**
|
|
* set labels and image from selected {@link Crop}
|
|
* set icons for buttons
|
|
* @param crop {@link Crop} which will be displayed
|
|
* @throws PlantNotFoundException exception
|
|
*/
|
|
public void setPlantFromCrop(Crop crop) throws PlantNotFoundException {
|
|
this.crop = crop;
|
|
try {
|
|
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
|
.orElseThrow(PlantNotFoundException::new);
|
|
|
|
cropName_label.setText(plant.name());
|
|
description_label.setText(plant.description());
|
|
light_label.setText(String.valueOf(plant.light()));
|
|
soil_label.setText(plant.soil());
|
|
spacing_label.setText(plant.spacing());
|
|
if (plant.image() != null) {
|
|
imageView.setImage(plant.image());
|
|
}
|
|
area_label.setText(String.valueOf(crop.getArea()));
|
|
|
|
initializeTaskListProperty(crop);
|
|
|
|
TaskList.TaskListObserver taskListObserver = newTaskList -> {
|
|
taskListProperty.clear();
|
|
taskListProperty.addAll(gardenSchedule.getTaskListForCrop(crop.getCropId().get()));
|
|
};
|
|
gardenSchedule.setTaskListObserver(taskListObserver);
|
|
|
|
taskList_listView.itemsProperty().bind(taskListProperty);
|
|
|
|
pestListProperty.addAll(plant.pests());
|
|
pests_listView.itemsProperty().bind(pestListProperty);
|
|
|
|
|
|
} catch (HardinessZoneNotSetException | IOException e) {
|
|
throw new PlantNotFoundException();
|
|
}
|
|
setIconToButton(addTask_button, "addIcon.png");
|
|
setIconToButton(area_button, "areaIcon.png");
|
|
setCellFactoryPests();
|
|
setCellFactoryTasks();
|
|
}
|
|
|
|
/**
|
|
* cell Factory for TaskListView
|
|
*/
|
|
private void setCellFactoryTasks() {
|
|
taskList_listView.setCellFactory(param -> new ListCell<>() {
|
|
@Override
|
|
protected void updateItem(Task task, boolean empty) {
|
|
super.updateItem(task, empty);
|
|
|
|
if (empty || task == null) {
|
|
setText(null);
|
|
setGraphic(null);
|
|
} else {
|
|
setText("");
|
|
setGraphic(createTaskHBox(task));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* cell Factory for PestListView
|
|
*/
|
|
private void setCellFactoryPests() {
|
|
pests_listView.setCellFactory(param -> new ListCell<>() {
|
|
@Override
|
|
protected void updateItem(Pest pest, boolean empty) {
|
|
super.updateItem(pest, empty);
|
|
|
|
if (empty || pest == null) {
|
|
setText(null);
|
|
setGraphic(null);
|
|
} else {
|
|
setText("");
|
|
setGraphic(createPestHBox(pest));
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* initialize task list
|
|
* @param crop {@link Crop} that is selected
|
|
*/
|
|
private void initializeTaskListProperty(Crop crop) {
|
|
crop.getCropId().ifPresent(id -> {
|
|
List<Task> taskList;
|
|
try {
|
|
taskList = gardenSchedule.getTaskListForCrop(id);
|
|
taskListProperty.clear();
|
|
taskListProperty.addAll(taskList);
|
|
} catch (IOException e) {
|
|
// TODO: Alert
|
|
LOG.log(Level.SEVERE, "Could not get task list for crop", e.getCause());
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a {@link HBox} for the given {@link Task}.
|
|
* @param task {@link Task} which is selected
|
|
* @return {@link HBox} that was created
|
|
*/
|
|
private HBox createTaskHBox(Task task) {
|
|
HBox hBox = new HBox(10);
|
|
Label taskName = new Label(task.getName()+": ");
|
|
taskName.setMinWidth(100);
|
|
taskName.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
|
|
taskName.setStyle("-fx-font-weight: bold");
|
|
Label taskDescription = new Label(task.getDescription());
|
|
taskDescription.setWrapText(true);
|
|
taskDescription.setMaxSize(600, Double.MAX_VALUE);
|
|
Pane puffer = new Pane();
|
|
HBox.setHgrow(puffer, Priority.ALWAYS);
|
|
|
|
|
|
Button edit = new Button();
|
|
Button delete = new Button();
|
|
edit.getStyleClass().add("button-class");
|
|
delete.getStyleClass().add("button-class");
|
|
HBox.setHgrow(edit, Priority.NEVER);
|
|
HBox.setHgrow(delete, Priority.NEVER);
|
|
setIconToButton(edit, "editIcon.png");
|
|
setIconToButton(delete, "deleteIcon.png");
|
|
edit.setOnAction(getEditTaskEvent(task));
|
|
delete.setOnAction(deleteTask(task));
|
|
|
|
hBox.getChildren().addAll(taskName, taskDescription, puffer, edit, delete);
|
|
return hBox;
|
|
}
|
|
|
|
/**
|
|
* Creates a {@link HBox} for the given {@link Pest}.
|
|
* @param pest {@link Pest} which is selected
|
|
* @return {@link HBox} that was created
|
|
*/
|
|
private HBox createPestHBox(Pest pest) {
|
|
Label label = new Label(pest.name() + ": ");
|
|
label.setStyle("-fx-font-weight: bold");
|
|
HBox hBox = new HBox();
|
|
hBox.fillHeightProperty();
|
|
Label description = new Label(pest.description());
|
|
description.setAlignment(Pos.TOP_LEFT);
|
|
description.setWrapText(true);
|
|
description.setMaxWidth(800);
|
|
hBox.getChildren().addAll(label, description);
|
|
return hBox;
|
|
}
|
|
|
|
/**
|
|
* adds icon to button
|
|
* @param button the button which get the icon
|
|
* @param iconFileName file name of icon
|
|
*/
|
|
private void setIconToButton(Button button, String iconFileName) {
|
|
Image img = new Image(String.valueOf(getClass().getResource("icons/" + iconFileName)));
|
|
ImageView imageView = new ImageView(img);
|
|
imageView.setFitHeight(20);
|
|
imageView.setPreserveRatio(true);
|
|
button.setGraphic(imageView);
|
|
}
|
|
|
|
/**
|
|
* opens dialog of {@link Task} edit.
|
|
* @param task {@link Task}
|
|
* @return {@link EventHandler} for the case of editing a {@link Task}
|
|
*/
|
|
private EventHandler<ActionEvent> getEditTaskEvent(Task task) {
|
|
return (event) -> {
|
|
try {
|
|
createTaskDialog(false, task);
|
|
} catch (IOException | HardinessZoneNotSetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* opens alert of {@link Task} deletion.
|
|
* @param task {@link Task}
|
|
* @return {@link EventHandler} for the case of deleting a {@link Task}
|
|
*/
|
|
private EventHandler<ActionEvent> deleteTask(Task task) {
|
|
return (event) -> {
|
|
showDeleteTask(task);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* opens a dialog to create a new Task or edit the given Task
|
|
* @param newTask boolean if it is a new Task
|
|
* @param givenTask {@link Task} which was selected
|
|
* @throws IOException Exception
|
|
* @throws HardinessZoneNotSetException Exception
|
|
*/
|
|
private void createTaskDialog(boolean newTask, Task givenTask) throws IOException, HardinessZoneNotSetException {
|
|
Dialog<Task> dialog = new Dialog<>();
|
|
dialog.setTitle("Set Task");
|
|
dialog.setHeaderText("Add/Edit Task:");
|
|
dialog.setResizable(false);
|
|
|
|
DialogPane dialogPane = dialog.getDialogPane();
|
|
|
|
dialogPane.getStylesheets().add(
|
|
Objects.requireNonNull(getClass().getResource("bootstrap/dialogStyle.css")).toExternalForm());
|
|
dialogPane.getStyleClass().add("myDialog");
|
|
|
|
ButtonType saveTask;
|
|
if(newTask) {
|
|
saveTask = new ButtonType("Add", ButtonBar.ButtonData.OK_DONE);
|
|
} else {
|
|
saveTask = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
|
}
|
|
dialogPane.getButtonTypes().addAll(saveTask, ButtonType.CANCEL);
|
|
|
|
if (appLoader.loadPaneToDialog("TaskFormular.fxml", dialogPane) instanceof TaskFormularController controller) {
|
|
controller.setCorp(this.crop);
|
|
controller.initSaveButton((Button) dialogPane.lookupButton(saveTask));
|
|
if (!newTask) {
|
|
controller.setTaskValue(givenTask);
|
|
}
|
|
dialog.setResultConverter(button -> button.equals(saveTask) ? controller.returnResult(this.crop) : null);
|
|
|
|
dialog.showAndWait()
|
|
.ifPresent(task -> {
|
|
if (newTask) {
|
|
try {
|
|
gardenSchedule.addTask(task);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
} else {
|
|
try {
|
|
gardenSchedule.addTask(givenTask.updateTask(task));
|
|
} catch (IOException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* opens TextField Dialog to enter the plant area.
|
|
* @throws IOException Exception
|
|
*/
|
|
private void openTextFieldDialog() throws IOException {
|
|
Dialog<String> dialog = new Dialog<>();
|
|
dialog.setTitle("set Text Area");
|
|
dialog.setHeaderText("set Text Area");
|
|
dialog.setResizable(false);
|
|
|
|
DialogPane dialogPane = dialog.getDialogPane();
|
|
|
|
dialogPane.getStylesheets().add(
|
|
Objects.requireNonNull(getClass().getResource("bootstrap/dialogStyle.css")).toExternalForm());
|
|
dialogPane.getStyleClass().add("myDialog");
|
|
|
|
ButtonType save = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
|
dialogPane.getButtonTypes().addAll(save, ButtonType.CANCEL);
|
|
|
|
if (appLoader.loadPaneToDialog("TextFieldFormular.fxml", dialogPane) instanceof TextFieldFormularController controller) {
|
|
controller.setDescription_label("Text Area");
|
|
controller.setValueTextArea(area_label.getText());
|
|
controller.initSaveButton((Button) dialogPane.lookupButton(save));
|
|
|
|
dialog.setResultConverter(button -> button.equals(save) ? controller.getValue() : null);
|
|
|
|
dialog.showAndWait()
|
|
.ifPresent(string -> {
|
|
try {
|
|
garden.updateCrop(this.crop.withArea(Double.parseDouble(string)));
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
area_label.setText(string);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Alert to delete Task.
|
|
* @param task {@link Task} which is being deleted
|
|
*/
|
|
private void showDeleteTask(Task task) {
|
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
alert.setTitle("Delete " + task.getName());
|
|
alert.setHeaderText("Are you sure want to delete this Task?");
|
|
|
|
DialogPane dialogPane = alert.getDialogPane();
|
|
|
|
dialogPane.getStylesheets().add(
|
|
Objects.requireNonNull(getClass().getResource("bootstrap/dialogStyle.css")).toExternalForm());
|
|
dialogPane.getStyleClass().add("myDialog");
|
|
|
|
alert.showAndWait()
|
|
.ifPresent(buttonType -> {
|
|
if (buttonType == ButtonType.OK) {
|
|
try {
|
|
gardenSchedule.removeTask(task);
|
|
//setTaskListProperty(this.crop);
|
|
} catch (IOException e) {
|
|
// TODO: Show error alert
|
|
LOG.log(Level.SEVERE, "Could not remove crop.", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|