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.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.logging.Level; import java.util.logging.Logger; 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 taskListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); private final ListProperty 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 taskList_listView; @FXML private ListView 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())); setTaskListProperty(crop); 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(); } 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)); } } }); } 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)); } } }); } private void setTaskListProperty(Crop crop) { crop.getCropId().ifPresent(id -> { List 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()); } }); } 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(); 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; } 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); } private EventHandler getEditTaskEvent(Task task) { return (event) -> { try { createTaskDialog(false, task); } catch (IOException | HardinessZoneNotSetException e) { e.printStackTrace(); } }; } private EventHandler deleteTask(Task task) { return (event) -> { showDeleteTask(task); }; } private void createTaskDialog(boolean newTask, Task givenTask) throws IOException, HardinessZoneNotSetException { Dialog dialog = new Dialog<>(); dialog.setTitle("Set Task"); dialog.setHeaderText("Add/Edit Task:"); dialog.setResizable(false); DialogPane dialogPane = dialog.getDialogPane(); 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); setTaskListProperty(this.crop); } catch (IOException e) { e.printStackTrace(); } } else { //ToDo method to edit task setTaskListProperty(this.crop); } }); } } private void openTextFieldDialog() throws IOException { Dialog dialog = new Dialog<>(); dialog.setTitle("set Text Area"); dialog.setHeaderText("set Text Area"); dialog.setResizable(false); DialogPane dialogPane = dialog.getDialogPane(); 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); }); } } 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?"); 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); } } }); } }