Compare commits

..

3 Commits

6 changed files with 103 additions and 42 deletions

View File

@ -20,7 +20,6 @@ import javafx.scene.Scene;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import javafx.stage.Modality; import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
@ -55,17 +54,17 @@ public class PlantsController implements Initializable {
private ListView<Plant> list_plants; private ListView<Plant> list_plants;
@FXML @FXML
private Button saveToMyPlant_button; private Button selectSowDay_button;
@FXML @FXML
private TextField search_plants; private TextField search_plants;
/** /**
* saves the current selected plant in new JSON database * open new window to select sow or harvest day to save the crop
* @param event event * @param event event
*/ */
@FXML @FXML
void saveToMyPlant(ActionEvent event) throws IOException { void selectSowDate(ActionEvent event) throws IOException {
Parent root; Parent root;
FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("SelectSowDay.fxml"))); FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("SelectSowDay.fxml")));
root = fxmlLoader.load(); root = fxmlLoader.load();
@ -92,7 +91,7 @@ public class PlantsController implements Initializable {
list_plants.itemsProperty().bind(plantListProperty); list_plants.itemsProperty().bind(plantListProperty);
description_plant.setText(""); description_plant.setText("");
saveToMyPlant_button.setDisable(true); selectSowDay_button.setDisable(true);
createFilterSeasons(); createFilterSeasons();
createFilterHardinessZone(); createFilterHardinessZone();
@ -202,7 +201,7 @@ public class PlantsController implements Initializable {
private void createFilterSeasons() { private void createFilterSeasons() {
ToggleGroup seasonGroup = new ToggleGroup(); ToggleGroup seasonGroup = new ToggleGroup();
for (Seasons season : Seasons.values()) { for (Seasons season : Seasons.values()) {
RadioButton radioButton = new RadioButton(season.name()); RadioButton radioButton = new RadioButton(season.getName());
radioButton.setToggleGroup(seasonGroup); radioButton.setToggleGroup(seasonGroup);
radioButton.setPadding(new Insets(0,0,10,0)); radioButton.setPadding(new Insets(0,0,10,0));
if (season.equals(Seasons.AllSEASONS)) { if (season.equals(Seasons.AllSEASONS)) {
@ -233,13 +232,18 @@ public class PlantsController implements Initializable {
* image of the plant * image of the plant
*/ */
private void lookForSelectedListEntry() { private void lookForSelectedListEntry() {
selectedPlant = null;
description_plant.setText("");
selectSowDay_button.setDisable(true);
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
img_plant.setImage(img);
list_plants.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Plant>() { list_plants.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Plant>() {
@Override @Override
public void changed(ObservableValue<? extends Plant> observable, Plant oldValue, Plant newValue) { public void changed(ObservableValue<? extends Plant> observable, Plant oldValue, Plant newValue) {
if(newValue != null) { if(newValue != null) {
selectedPlant = newValue; selectedPlant = newValue;
description_plant.setText(selectedPlant.description()); description_plant.setText(selectedPlant.description());
saveToMyPlant_button.setDisable(false); selectSowDay_button.setDisable(false);
Image img; Image img;
if(selectedPlant.image() != null) { if(selectedPlant.image() != null) {
img = selectedPlant.image(); img = selectedPlant.image();
@ -247,12 +251,10 @@ public class PlantsController implements Initializable {
img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
} }
img_plant.setImage(img); img_plant.setImage(img);
} else { } else {
selectedPlant = null; selectedPlant = null;
description_plant.setText(""); description_plant.setText("");
saveToMyPlant_button.setDisable(true); selectSowDay_button.setDisable(true);
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png"))); Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
img_plant.setImage(img); img_plant.setImage(img);
} }

View File

@ -31,31 +31,50 @@ public class SelectSowDayController implements Initializable {
@FXML @FXML
private RadioButton sow_radio; private RadioButton sow_radio;
/**
* close the date selector window
* @param event event
*/
@FXML @FXML
void cancel(ActionEvent event) { void cancel(ActionEvent event) {
closeWindow(); closeWindow();
} }
/**
* get sow date from datePicker or calculate sow date from harvest date
* save selected plant and sow date
* @param event event
*/
@FXML @FXML
void save(ActionEvent event) { void save(ActionEvent event) {
//ToDo save plant and sow date to crop/gardenplan model //ToDo save plant and sow date to crop/gardenplan model
System.out.println(selectedPlant); LocalDate sowDate;
if (sow_radio.isSelected()) { if (sow_radio.isSelected()) {
System.out.println(datepicker.getValue()); sowDate = datepicker.getValue();
} else { } else {
//ToDo method to get current lifecycle group in plant //ToDo method to get current lifecycle group in plant
//ToDo error when sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
//what's up with that group thing in life_cycle we have hardiness zone for that
System.out.println(selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0));
} }
System.out.println(sowDate);
System.out.println(selectedPlant);
closeWindow(); closeWindow();
} }
/**
* save the plant which will be planted and update label
* @param plant Plant
*/
public void getSelectedPlant(Plant plant) { public void getSelectedPlant(Plant plant) {
selectedPlant = plant; selectedPlant = plant;
popup_label.setText("Select Harvest/Sow Date for" + selectedPlant.name()); popup_label.setText("Select Harvest/Sow Date for" + selectedPlant.name());
} }
/**
* add listener and set default values
* {@inheritDoc}
* @param location location
* @param resources resources
*/
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
clearDatePickerEntries(); clearDatePickerEntries();
@ -67,6 +86,9 @@ public class SelectSowDayController implements Initializable {
enableDisableSaveButton(); enableDisableSaveButton();
} }
/**
* clear date picker editor when radio button is changed
*/
private void clearDatePickerEntries() { private void clearDatePickerEntries() {
sow_radio.selectedProperty().addListener(new ChangeListener<Boolean>() { sow_radio.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override @Override
@ -76,6 +98,10 @@ public class SelectSowDayController implements Initializable {
}); });
} }
/**
* date picker disable/enable dates according to selected plant: sow or harvest day
* @return cellFactory of datePicker
*/
private Callback<DatePicker, DateCell> getDayCellFactory() { private Callback<DatePicker, DateCell> getDayCellFactory() {
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() { final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
@ -103,6 +129,10 @@ public class SelectSowDayController implements Initializable {
setStyle("-fx-background-color: #32CD32;"); setStyle("-fx-background-color: #32CD32;");
} }
} }
if ((!sow_radio.isSelected() && selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) < 0)) {
setDisable(true);
setStyle("-fx-background-color: #ffc0cb;");
}
} }
}; };
} }
@ -110,11 +140,17 @@ public class SelectSowDayController implements Initializable {
return dayCellFactory; return dayCellFactory;
} }
/**
* close date picker window
*/
private void closeWindow() { private void closeWindow() {
Stage stage = (Stage) save_button.getScene().getWindow(); Stage stage = (Stage) save_button.getScene().getWindow();
stage.close(); stage.close();
} }
/**
* disable save button, when there is no date selected in date picker
*/
private void enableDisableSaveButton() { private void enableDisableSaveButton() {
save_button.setDisable(true); save_button.setDisable(true);
datepicker.getEditor().textProperty().addListener(new ChangeListener<String>() { datepicker.getEditor().textProperty().addListener(new ChangeListener<String>() {

View File

@ -20,20 +20,40 @@ public record Plant(
List<Pest> pests, List<Pest> pests,
List<GrowthPhase> lifecycle) { List<GrowthPhase> lifecycle) {
/**
* remove all growthPhase which do not belong to the hardiness zone
* @param zone hardiness zone
*/
public void inZone(HardinessZone zone) { public void inZone(HardinessZone zone) {
lifecycle.removeIf(growthPhase -> !growthPhase.zone().equals(zone)); lifecycle.removeIf(growthPhase -> !growthPhase.zone().equals(zone));
} }
/**
* get all growthPhases of lifecycle group
* @param group lifecycle group
* @return list of growthPhases
*/
public List<GrowthPhase> lifecycleForGroup(int group) { public List<GrowthPhase> lifecycleForGroup(int group) {
return lifecycle.stream() return lifecycle.stream()
.filter(growthPhase -> growthPhase.group() != group) .filter(growthPhase -> growthPhase.group() == group)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/**
* get sow date from given harvest day from lifecycle group
* @param harvestDate date of the harvest
* @param group lifecycle group
* @return LocaleDate of sow date
*/
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate, int group) { public LocalDate sowDateFromHarvestDate(LocalDate harvestDate, int group) {
return harvestDate.minusDays(timeToHarvest(group)); return harvestDate.minusDays(timeToHarvest(group));
} }
/**
* calculate the days between sow and harvest day for lifecycle group
* @param group the lifecycle group
* @return Integer number of dates between sow and harvest day
*/
public int timeToHarvest(int group) { public int timeToHarvest(int group) {
List<GrowthPhase> activeLifecycle = lifecycleForGroup(group); List<GrowthPhase> activeLifecycle = lifecycleForGroup(group);
GrowthPhase sow = activeLifecycle.stream() GrowthPhase sow = activeLifecycle.stream()
@ -49,6 +69,12 @@ public record Plant(
return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear)); return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear));
} }
/**
* filter out the given growthPhase out of the lifecycle
* create list of dates for this growthPhase and return it
* @param growthPhase the wanted growthPhase
* @return a list of dates of the current year
*/
public List<LocalDate> getDateListOfGrowthPhase(GrowthPhaseType growthPhase) { public List<LocalDate> getDateListOfGrowthPhase(GrowthPhaseType growthPhase) {
List<LocalDate> dates = new LinkedList<>(); List<LocalDate> dates = new LinkedList<>();
for (GrowthPhase growth : lifecycle) { for (GrowthPhase growth : lifecycle) {
@ -56,12 +82,15 @@ public record Plant(
dates = addDatesFromMonthDay(growth); dates = addDatesFromMonthDay(growth);
} }
} }
if (growthPhase.equals(GrowthPhaseType.HARVEST)) {
return removeDatesForPassedSowDates(dates);
}
return dates; return dates;
} }
/**
* transform monthDay value of the given growthPhase to localDate
* return a list of dates from start to end of growth phase
* @param growthPhase the current growthPhase
* @return a list of dates of the current year
*/
private List<LocalDate> addDatesFromMonthDay(GrowthPhase growthPhase) { private List<LocalDate> addDatesFromMonthDay(GrowthPhase growthPhase) {
List<LocalDate> dates = new LinkedList<>(); List<LocalDate> dates = new LinkedList<>();
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
@ -73,9 +102,4 @@ public record Plant(
} }
return dates; return dates;
} }
private List<LocalDate> removeDatesForPassedSowDates(List<LocalDate> dates) {
//ToDo Remove harvest dates where sow dates have already passed current day
return dates;
}
} }

View File

@ -3,18 +3,20 @@ package ch.zhaw.gartenverwaltung.types;
import java.time.MonthDay; import java.time.MonthDay;
public enum Seasons { public enum Seasons {
AllSEASONS("--01-01", "--12-31"), AllSEASONS("--01-01", "--12-31", "All Seasons"),
SPRING("--03-01", "--05-30"), SPRING("--03-01", "--05-30", "Spring"),
SOMMER("--06-01", "--08-30"), SUMMER("--06-01", "--08-30", "Summer"),
AUTUM("--09-01", "--11-30"), AUTUMN("--09-01", "--11-30", "Autumn"),
WINTER("--12-01", "--02-28"); WINTER("--12-01", "--02-28", "Winter");
public final String startDate; public final String startDate;
public final String endDate; public final String endDate;
public final String name;
Seasons(String startDate, String endDate) { Seasons(String startDate, String endDate, String name) {
this.startDate = startDate; this.startDate = startDate;
this.endDate = endDate; this.endDate = endDate;
this.name = name;
} }
public MonthDay getStartDate() { public MonthDay getStartDate() {
@ -23,4 +25,7 @@ public enum Seasons {
public MonthDay getEndDate() { public MonthDay getEndDate() {
return MonthDay.parse(this.endDate); return MonthDay.parse(this.endDate);
} }
public String getName() {
return this.name;
}
} }

View File

@ -1,14 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.geometry.Rectangle2D?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?> <?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?> <?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?> <?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?> <?import javafx.scene.control.TitledPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
@ -33,15 +31,8 @@
<TextField fx:id="search_plants" promptText="Search for Plant Name" /> <TextField fx:id="search_plants" promptText="Search for Plant Name" />
<HBox alignment="CENTER_LEFT" prefHeight="480.0" prefWidth="881.0" VBox.vgrow="ALWAYS"> <HBox alignment="CENTER_LEFT" prefHeight="480.0" prefWidth="881.0" VBox.vgrow="ALWAYS">
<children> <children>
<ListView fx:id="list_plants" maxWidth="1.7976931348623157E308" prefHeight="497.0" prefWidth="580.0" HBox.hgrow="ALWAYS" /> <ListView fx:id="list_plants" maxWidth="1.7976931348623157E308" prefHeight="497.0" prefWidth="400.0" HBox.hgrow="ALWAYS" />
<ImageView fx:id="img_plant" fitHeight="322.0" fitWidth="861.0" pickOnBounds="true" preserveRatio="true" HBox.hgrow="NEVER"> <ImageView fx:id="img_plant" fitWidth="300" pickOnBounds="true" preserveRatio="true" HBox.hgrow="NEVER" />
<viewport>
<Rectangle2D height="300.0" width="300.0" />
</viewport>
<image>
<Image url="@placeholder.png" />
</image>
</ImageView>
</children> </children>
</HBox> </HBox>
<Label prefHeight="33.0" prefWidth="919.0" text="Plant Information:"> <Label prefHeight="33.0" prefWidth="919.0" text="Plant Information:">
@ -57,7 +48,7 @@
<Insets bottom="10.0" top="10.0" /> <Insets bottom="10.0" top="10.0" />
</padding> </padding>
</Label> </Label>
<Button fx:id="saveToMyPlant_button" alignment="CENTER" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#saveToMyPlant" prefHeight="38.0" prefWidth="917.0" text="Save to MyPlants" /> <Button fx:id="selectSowDay_button" alignment="CENTER" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#selectSowDate" prefHeight="38.0" prefWidth="917.0" text="Select Harvest/Sow Day" />
</children> </children>
</VBox> </VBox>
</children> </children>

View File

@ -94,6 +94,7 @@
"endDate": "03-10", "endDate": "03-10",
"zone": "ZONE_8A", "zone": "ZONE_8A",
"type": "SOW", "type": "SOW",
"group": 0,
"wateringCycle": { "wateringCycle": {
"litersPerSqM": 15, "litersPerSqM": 15,
"interval": 3, "interval": 3,
@ -115,6 +116,7 @@
"endDate": "05-10", "endDate": "05-10",
"zone": "ZONE_8A", "zone": "ZONE_8A",
"type": "PLANT", "type": "PLANT",
"group": 0,
"wateringCycle": { "wateringCycle": {
"litersPerSqM": 25, "litersPerSqM": 25,
"interval": 3, "interval": 3,
@ -138,6 +140,7 @@
"endDate": "05-20", "endDate": "05-20",
"zone": "ZONE_8A", "zone": "ZONE_8A",
"type": "HARVEST", "type": "HARVEST",
"group": 0,
"wateringCycle": { "wateringCycle": {
"litersPerSqM": 0, "litersPerSqM": 0,
"interval": null, "interval": null,