From efc95dbcc6233bc657a9d33603c038438ae4f918 Mon Sep 17 00:00:00 2001 From: giavaphi Date: Wed, 2 Nov 2022 19:33:27 +0100 Subject: [PATCH 1/4] #46 DatePicker for sow and harvest day --- .../gartenverwaltung/PlantsController.java | 24 +++- .../SelectSowDayController.java | 131 ++++++++++++++++++ .../ch/zhaw/gartenverwaltung/types/Plant.java | 31 +++++ .../zhaw/gartenverwaltung/SelectSowDay.fxml | 57 ++++++++ 4 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java create mode 100644 src/main/resources/ch/zhaw/gartenverwaltung/SelectSowDay.fxml diff --git a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java index 5554d3d..894fb87 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java @@ -5,7 +5,6 @@ import ch.zhaw.gartenverwaltung.plantList.PlantListModel; import ch.zhaw.gartenverwaltung.types.HardinessZone; import ch.zhaw.gartenverwaltung.types.Plant; import ch.zhaw.gartenverwaltung.types.Seasons; -import javafx.application.Platform; import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; import javafx.beans.value.ChangeListener; @@ -13,18 +12,23 @@ import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.geometry.Insets; -import javafx.geometry.Bounds; +import javafx.scene.Parent; +import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.input.KeyEvent; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; +import javafx.stage.Modality; +import javafx.stage.Stage; import java.io.IOException; import java.net.URL; import java.util.List; +import java.util.Objects; import java.util.ResourceBundle; public class PlantsController implements Initializable { @@ -33,7 +37,6 @@ public class PlantsController implements Initializable { private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A; // TODO: move to model - private final ListProperty plantListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); @FXML @@ -62,8 +65,17 @@ public class PlantsController implements Initializable { * @param event event */ @FXML - void saveToMyPlant(ActionEvent event) { - //ToDo model save selectedPlant to mySelectedPlant(IO) + void saveToMyPlant(ActionEvent event) throws IOException { + Parent root; + FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("SelectSowDay.fxml"))); + root = fxmlLoader.load(); + SelectSowDayController controller = fxmlLoader.getController(); + controller.getSelectedPlant(selectedPlant); + Stage stage = new Stage(); + stage.setScene(new Scene(root)); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setResizable(false); + stage.showAndWait(); } /** diff --git a/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java b/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java new file mode 100644 index 0000000..e5e80f4 --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java @@ -0,0 +1,131 @@ +package ch.zhaw.gartenverwaltung; + +import ch.zhaw.gartenverwaltung.types.GrowthPhaseType; +import ch.zhaw.gartenverwaltung.types.Plant; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.*; +import javafx.stage.Stage; +import javafx.util.Callback; + +import java.net.URL; +import java.time.LocalDate; +import java.util.List; +import java.util.ResourceBundle; + +public class SelectSowDayController implements Initializable { + private Plant selectedPlant = null; + + @FXML + private DatePicker datepicker; + + @FXML + private Label popup_label; + + @FXML + private Button save_button; + + @FXML + private RadioButton sow_radio; + + @FXML + void cancel(ActionEvent event) { + closeWindow(); + } + + @FXML + void save(ActionEvent event) { + //ToDo save plant and sow date to crop/gardenplan model + System.out.println(selectedPlant); + if (sow_radio.isSelected()) { + System.out.println(datepicker.getValue()); + } else { + //ToDo method to get current lifecycle group in plant + //ToDo error when + //what's up with that group thing in life_cycle we have hardiness zone for that + System.out.println(selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0)); + } + closeWindow(); + } + + public void getSelectedPlant(Plant plant) { + selectedPlant = plant; + popup_label.setText("Select Harvest/Sow Date for" + selectedPlant.name()); + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + clearDatePickerEntries(); + + Callback dayCellFactory= getDayCellFactory(); + datepicker.setDayCellFactory(dayCellFactory); + datepicker.getEditor().setEditable(false); + + enableDisableSaveButton(); + } + + private void clearDatePickerEntries() { + sow_radio.selectedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Boolean oldValue, Boolean isNowSelected) { + datepicker.getEditor().clear(); + } + }); + } + + private Callback getDayCellFactory() { + + final Callback dayCellFactory = new Callback() { + + @Override + public DateCell call(final DatePicker datePicker) { + return new DateCell() { + @Override + public void updateItem(LocalDate item, boolean empty) { + super.updateItem(item, empty); + setDisable(true); + setStyle("-fx-background-color: #ffc0cb;"); + List dates; + LocalDate today = LocalDate.now(); + if (sow_radio.isSelected()) { + dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW); + } else { + dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST); + } + for (LocalDate date : dates) { + if (item.getMonth() == date.getMonth() + && item.getDayOfMonth() == date.getDayOfMonth() + && item.compareTo(today) > 0) { + setDisable(false); + setStyle("-fx-background-color: #32CD32;"); + } + } + } + }; + } + }; + return dayCellFactory; + } + + private void closeWindow() { + Stage stage = (Stage) save_button.getScene().getWindow(); + stage.close(); + } + + private void enableDisableSaveButton() { + save_button.setDisable(true); + datepicker.getEditor().textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + if (newValue == null || newValue.equals("")) { + save_button.setDisable(true); + } else { + save_button.setDisable(false); + } + } + }); + } +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java b/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java index 3250b4f..2a2bc0b 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/Plant.java @@ -3,6 +3,7 @@ package ch.zhaw.gartenverwaltung.types; import javafx.scene.image.Image; import java.time.LocalDate; +import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; @@ -47,4 +48,34 @@ public record Plant( int currentYear = LocalDate.now().getYear(); return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear)); } + + public List getDateListOfGrowthPhase(GrowthPhaseType growthPhase) { + List dates = new LinkedList<>(); + for (GrowthPhase growth : lifecycle) { + if (growth.type().equals(growthPhase)) { + dates = addDatesFromMonthDay(growth); + } + } + if (growthPhase.equals(GrowthPhaseType.HARVEST)) { + return removeDatesForPassedSowDates(dates); + } + return dates; + } + + private List addDatesFromMonthDay(GrowthPhase growthPhase) { + List dates = new LinkedList<>(); + LocalDate today = LocalDate.now(); + LocalDate start = growthPhase.startDate().atYear(today.getYear()); + LocalDate end = growthPhase.endDate().atYear(today.getYear()); + while (!start.isAfter(end)) { + dates.add(start); + start = start.plusDays(1); + } + return dates; + } + + private List removeDatesForPassedSowDates(List dates) { + //ToDo Remove harvest dates where sow dates have already passed current day + return dates; + } } diff --git a/src/main/resources/ch/zhaw/gartenverwaltung/SelectSowDay.fxml b/src/main/resources/ch/zhaw/gartenverwaltung/SelectSowDay.fxml new file mode 100644 index 0000000..ae44b29 --- /dev/null +++ b/src/main/resources/ch/zhaw/gartenverwaltung/SelectSowDay.fxml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + +