package ch.zhaw.gartenverwaltung; import ch.zhaw.gartenverwaltung.bootstrap.AfterInject; import ch.zhaw.gartenverwaltung.bootstrap.AppLoader; import ch.zhaw.gartenverwaltung.bootstrap.ChangeViewEvent; 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.PlantNotFoundException; import ch.zhaw.gartenverwaltung.types.Crop; import ch.zhaw.gartenverwaltung.types.Plant; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.stage.Modality; import javafx.stage.Stage; import java.io.IOException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; public class MyGardenController { private static final Logger LOG = Logger.getLogger(MyGardenController.class.getName()); @Inject AppLoader appLoader; @Inject private Garden garden; @Inject private PlantList plantList; @FXML public AnchorPane myGardenRoot; @FXML private Button addPlant_button; @FXML private ListView myGarden_listView; /** * initialize crop list * add listener for crop list * set icon for button */ @AfterInject @SuppressWarnings("unused") public void init() { System.out.println("once"); setIconToButton(addPlant_button, "addIcon.png"); myGarden_listView.itemsProperty().bind(garden.getPlantedCrops()); setCellFactory(); } /** * redirect to plant fxml file */ @FXML void addPlant() { myGardenRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "Plants.fxml")); } /** * set cell factory to load {@link HBox} as list view content */ private void setCellFactory() { myGarden_listView.setCellFactory(param -> new ListCell<>() { @Override protected void updateItem(Crop crop, boolean empty) { super.updateItem(crop, empty); if (empty || crop == null) { setText(null); setGraphic(null); } else { try { setText(""); setGraphic(createHBoxForListView(crop)); } catch (HardinessZoneNotSetException | IOException e) { LOG.log(Level.WARNING, "Could not get plant for Cell", e); } } } }); } /** * Creates and returns HBox of the crop * @param crop {@link Crop} which is selected * @return {@link HBox} of the {@link Crop} * @throws HardinessZoneNotSetException exception * @throws IOException exception */ private HBox createHBoxForListView(Crop crop) throws HardinessZoneNotSetException, IOException { //ToDo add better design Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(); HBox hBox = new HBox(10); ImageView imageView = new ImageView(); imageView.setPreserveRatio(false); imageView.setFitHeight(100); imageView.setFitWidth(100); imageView.maxHeight(100); if (plant.image() != null) { imageView.setImage(plant.image()); } hBox.setMinHeight(100); Label label = new Label(plant.name()); label.setMaxWidth(2000); HBox.setHgrow(label, Priority.ALWAYS); Button details = new Button(); Button delete = new Button(); setIconToButton(details, "detailsIcon.png"); setIconToButton(delete, "deleteIcon.png"); details.setOnAction(getGoToCropDetailEvent(crop)); delete.setOnAction(getDeleteCropEvent(crop)); hBox.getChildren().addAll(imageView, label, details, delete); 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); } /** * open detail window of the selected {@link Crop} * @param crop {@link Crop} which is selected * @return {@link EventHandler} for button */ private EventHandler getGoToCropDetailEvent(Crop crop) { return (event) -> { try { Stage stage = new Stage(); if (appLoader.loadSceneToStage("CropDetail.fxml", stage) instanceof CropDetailController controller) { controller.setPlantFromCrop(crop); } stage.initModality(Modality.APPLICATION_MODAL); stage.setResizable(true); stage.showAndWait(); } catch (IOException | PlantNotFoundException e) { // TODO: show error alert LOG.log(Level.SEVERE, "Could not load plant details.", e); } }; } /** * open alert for deleting the selected {@link Crop} * @param crop {@link Crop} which is selected * @return {@link EventHandler} for button */ private EventHandler getDeleteCropEvent(Crop crop) { return (event) -> { try { showConfirmation(crop); } catch (IOException | HardinessZoneNotSetException e) { e.printStackTrace(); } }; } /** * Alert to confirm that the crop can be deleted. * @param crop {@link Crop} which is selected * @throws IOException exception * @throws HardinessZoneNotSetException exception */ private void showConfirmation(Crop crop) throws IOException, HardinessZoneNotSetException { Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(); Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle("Delete " + plant.name()); alert.setHeaderText("Are you sure want to delete this Crop?"); alert.setContentText("Deleting this crop will remove all associated tasks from your schedule."); alert.showAndWait() .ifPresent(buttonType -> { if (buttonType == ButtonType.OK) { try { garden.removeCrop(crop); } catch (IOException e) { // TODO: Show error alert LOG.log(Level.SEVERE, "Could not remove crop.", e); } } }); } }