commit
b70a758099
|
@ -93,23 +93,27 @@ public class CropDetailController {
|
|||
|
||||
}
|
||||
|
||||
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
||||
public void setPlantFromCrop(Crop crop) throws PlantNotFoundException {
|
||||
this.crop = crop;
|
||||
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
||||
.orElseThrow(PlantNotFoundException::new);
|
||||
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());
|
||||
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("");
|
||||
location_label.setText("");
|
||||
createTaskLists(crop);
|
||||
createPestList(plant);
|
||||
} catch (HardinessZoneNotSetException | IOException e) {
|
||||
throw new PlantNotFoundException();
|
||||
}
|
||||
area_label.setText("");
|
||||
location_label.setText("");
|
||||
createTaskLists(crop);
|
||||
createPestList(plant);
|
||||
}
|
||||
|
||||
private void createTaskLists(Crop crop) {
|
||||
|
|
|
@ -90,10 +90,12 @@ public class MyGardenController {
|
|||
Label label = new Label(plant.name());
|
||||
label.setMaxWidth(2000);
|
||||
HBox.setHgrow(label, Priority.ALWAYS);
|
||||
|
||||
Button details = new Button("Details");
|
||||
Button delete = new Button("delete");
|
||||
details.setOnAction(getGoToCropDetailEvent(crop));
|
||||
delete.setOnAction(getDeleteCropEvent(crop));
|
||||
|
||||
hBox.getChildren().addAll(imageView, label, details, delete);
|
||||
return hBox;
|
||||
}
|
||||
|
@ -108,7 +110,7 @@ public class MyGardenController {
|
|||
stage.initModality(Modality.APPLICATION_MODAL);
|
||||
stage.setResizable(true);
|
||||
stage.showAndWait();
|
||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
||||
} catch (IOException | PlantNotFoundException e) {
|
||||
// TODO: show error alert
|
||||
LOG.log(Level.SEVERE, "Could not load plant details.", e);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,6 @@ import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
|||
import ch.zhaw.gartenverwaltung.types.Crop;
|
||||
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.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
|
@ -37,8 +34,6 @@ public class MyScheduleController {
|
|||
@Inject
|
||||
private PlantList plantList;
|
||||
|
||||
private final ListProperty<Crop> cropListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||
|
||||
@FXML
|
||||
private Label day1_label;
|
||||
|
||||
|
@ -90,15 +85,8 @@ public class MyScheduleController {
|
|||
@AfterInject
|
||||
@SuppressWarnings("unused")
|
||||
public void init() {
|
||||
List<Crop> cropList;
|
||||
try {
|
||||
cropList = garden.getCrops();
|
||||
cropListProperty.addAll(cropList);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
setCellFactoryListView();
|
||||
scheduledPlants_listview.itemsProperty().bind(cropListProperty);
|
||||
scheduledPlants_listview.itemsProperty().bind(garden.getPlantedCrops());
|
||||
lookForSelectedListEntries();
|
||||
setDayLabels();
|
||||
information_label.setText("");
|
||||
|
|
|
@ -21,7 +21,6 @@ import javafx.scene.image.Image;
|
|||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
|
@ -74,7 +73,6 @@ public class PlantsController {
|
|||
*/
|
||||
@FXML
|
||||
void selectSowDate() throws IOException {
|
||||
Stage stage = new Stage();
|
||||
Dialog<LocalDate> dateSelection = new Dialog<>();
|
||||
dateSelection.setTitle("Select Date");
|
||||
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
||||
|
@ -85,22 +83,21 @@ public class PlantsController {
|
|||
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
||||
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
||||
|
||||
if (appLoader.loadSceneToStage("SelectSowDay.fxml", stage) instanceof SelectSowDayController controller) {
|
||||
if (appLoader.loadPaneToDialog("SelectSowDay.fxml", dialogPane) instanceof SelectSowDayController controller) {
|
||||
controller.initSaveButton((Button) dialogPane.lookupButton(sowButton));
|
||||
controller.setSelectedPlant(selectedPlant);
|
||||
dateSelection.setResultConverter(button -> button.equals(sowButton) ? controller.retrieveResult() : null);
|
||||
}
|
||||
dialogPane.setContent(stage.getScene().getRoot());
|
||||
|
||||
dateSelection.showAndWait()
|
||||
.ifPresent(date -> {
|
||||
try {
|
||||
garden.plantAsCrop(selectedPlant, date);
|
||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
||||
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
||||
}
|
||||
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
||||
});
|
||||
dateSelection.showAndWait()
|
||||
.ifPresent(date -> {
|
||||
try {
|
||||
garden.plantAsCrop(selectedPlant, date);
|
||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
||||
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
||||
}
|
||||
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,6 @@ import javafx.scene.control.*;
|
|||
import javafx.util.Callback;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
public class SelectSowDayController {
|
||||
private Plant selectedPlant;
|
||||
|
@ -17,12 +16,15 @@ public class SelectSowDayController {
|
|||
|
||||
@FXML
|
||||
private RadioButton harvest_radio;
|
||||
@FXML
|
||||
private RadioButton sow_radio;
|
||||
@FXML
|
||||
public ToggleGroup phase_group;
|
||||
|
||||
public LocalDate retrieveResult() {
|
||||
LocalDate sowDate = datepicker.getValue();
|
||||
if (harvest_radio.isSelected()) {
|
||||
//ToDo method to get current lifecycle group in plant
|
||||
sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
|
||||
sowDate = selectedPlant.sowDateFromHarvestDate(sowDate);
|
||||
}
|
||||
return sowDate;
|
||||
}
|
||||
|
@ -46,6 +48,9 @@ public class SelectSowDayController {
|
|||
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
||||
datepicker.setDayCellFactory(dayCellFactory);
|
||||
datepicker.setEditable(false);
|
||||
|
||||
sow_radio.setUserData(GrowthPhaseType.SOW);
|
||||
harvest_radio.setUserData(GrowthPhaseType.HARVEST);
|
||||
}
|
||||
|
||||
public void initSaveButton(Button saveButton) {
|
||||
|
@ -61,35 +66,28 @@ public class SelectSowDayController {
|
|||
|
||||
/**
|
||||
* date picker disable/enable dates according to selected plant: sow or harvest day
|
||||
*
|
||||
* @return cellFactory of datePicker
|
||||
*/
|
||||
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
||||
|
||||
return (datePicker) -> new DateCell() {
|
||||
private final LocalDate today = LocalDate.now();
|
||||
|
||||
@Override
|
||||
public void updateItem(LocalDate item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
setDisable(true);
|
||||
setStyle("-fx-background-color: #ffc0cb;");
|
||||
List<LocalDate> dates;
|
||||
LocalDate today = LocalDate.now();
|
||||
if (harvest_radio.isSelected()) {
|
||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
|
||||
} else {
|
||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
|
||||
}
|
||||
for (LocalDate date : dates) {
|
||||
if (item.getMonth() == date.getMonth()
|
||||
&& item.getDayOfMonth() == date.getDayOfMonth()
|
||||
&& item.compareTo(today) > 0) {
|
||||
|
||||
if (item.compareTo(today) > 0 && (!harvest_radio.isSelected() || selectedPlant.sowDateFromHarvestDate(item).compareTo(today) >= 0)) {
|
||||
GrowthPhaseType selectedPhase = (GrowthPhaseType) phase_group.getSelectedToggle().getUserData();
|
||||
|
||||
if (selectedPlant.isDateInPhase(item, selectedPhase)) {
|
||||
setDisable(false);
|
||||
setStyle("-fx-background-color: #32CD32;");
|
||||
}
|
||||
}
|
||||
if ((harvest_radio.isSelected() && selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) < 0)) {
|
||||
setDisable(true);
|
||||
setStyle("-fx-background-color: #ffc0cb;");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
|||
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.DialogPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
@ -78,6 +79,24 @@ public class AppLoader {
|
|||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given fxml-file from resources (no caching) and appendeds it's
|
||||
* contents to the given {@link DialogPane}.
|
||||
* Performs dependency-injection.
|
||||
*
|
||||
* @param fxmlFile The file name to be loaded
|
||||
* @param appendee The {@link DialogPane} to which the FXML contents are to be appended.
|
||||
* @return The controller of the loaded scene.
|
||||
* @throws IOException if the file could not be loaded
|
||||
*/
|
||||
public Object loadPaneToDialog(String fxmlFile, DialogPane appendee) throws IOException {
|
||||
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
||||
appendee.setContent(loader.load());
|
||||
Object controller = loader.getController();
|
||||
annotationInject(controller);
|
||||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given fxml-file from resources and caches the pane.
|
||||
* Performs dependency-injection.
|
||||
|
|
|
@ -3,7 +3,7 @@ package ch.zhaw.gartenverwaltung.types;
|
|||
import javafx.scene.image.Image;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.LinkedList;
|
||||
import java.time.MonthDay;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -42,11 +42,10 @@ public record Plant(
|
|||
/**
|
||||
* 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) {
|
||||
return harvestDate.minusDays(timeToHarvest(group));
|
||||
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate) {
|
||||
return harvestDate.minusDays(timeToHarvest(lifecycleGroupFromHarvestDate(harvestDate)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,37 +68,43 @@ public record Plant(
|
|||
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) {
|
||||
List<LocalDate> dates = new LinkedList<>();
|
||||
for (GrowthPhase growth : lifecycle) {
|
||||
if (growth.type().equals(growthPhase)) {
|
||||
dates = addDatesFromMonthDay(growth);
|
||||
}
|
||||
}
|
||||
return dates;
|
||||
public int lifecycleGroupFromHarvestDate(LocalDate harvestDate) {
|
||||
return lifecycle.stream()
|
||||
.filter(growthPhase -> growthPhase.type().equals(GrowthPhaseType.HARVEST) &&
|
||||
dateInRange(harvestDate, growthPhase.startDate(), growthPhase.endDate()))
|
||||
.map(GrowthPhase::group)
|
||||
.findFirst()
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Checks if the given {@link LocalDate} is within a {@link GrowthPhase} of the given {@link GrowthPhaseType}
|
||||
*
|
||||
* @param date The date to check.
|
||||
* @param phase The {@link GrowthPhaseType} to match against
|
||||
* @return Whether the date is within the given {@link GrowthPhaseType}
|
||||
*/
|
||||
private List<LocalDate> addDatesFromMonthDay(GrowthPhase growthPhase) {
|
||||
List<LocalDate> 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;
|
||||
public boolean isDateInPhase(LocalDate date, GrowthPhaseType phase) {
|
||||
return lifecycle.stream()
|
||||
.filter(growthPhase -> growthPhase.type().equals(phase))
|
||||
.anyMatch(growthPhase -> dateInRange(date, growthPhase.startDate(), growthPhase.endDate()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given {@link LocalDate} is within the given {@link MonthDay} range.
|
||||
* (regardless of year)
|
||||
*
|
||||
* @param subject The date to check
|
||||
* @param min The start of the date-range
|
||||
* @param max The end of the date-range
|
||||
* @return Whether the subject is within the range.
|
||||
*/
|
||||
private boolean dateInRange(LocalDate subject, MonthDay min, MonthDay max) {
|
||||
return subject.getMonth().compareTo(min.getMonth()) >= 0 &&
|
||||
subject.getMonth().compareTo(max.getMonth()) <= 0 &&
|
||||
// if the day is less than the minimum day, the minimum month must not be equal
|
||||
(subject.getDayOfMonth() >= min.getDayOfMonth() || !subject.getMonth().equals(min.getMonth())) &&
|
||||
// if the day is greater than the maximum day, the maximum month must not be equal
|
||||
(subject.getDayOfMonth() <= max.getDayOfMonth() || !subject.getMonth().equals(max.getMonth()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@
|
|||
<children>
|
||||
<VBox alignment="CENTER_LEFT" prefHeight="88.0" prefWidth="155.0">
|
||||
<children>
|
||||
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow" toggleGroup="$group">
|
||||
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow" toggleGroup="$phase_group">
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" />
|
||||
</VBox.margin>
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="group" />
|
||||
<ToggleGroup fx:id="phase_group" />
|
||||
</toggleGroup>
|
||||
</RadioButton>
|
||||
<RadioButton fx:id="harvest_radio" mnemonicParsing="false" text="Harvest" toggleGroup="$group" />
|
||||
<RadioButton fx:id="harvest_radio" mnemonicParsing="false" text="Harvest" toggleGroup="$phase_group" />
|
||||
</children>
|
||||
<HBox.margin>
|
||||
<Insets top="10.0" />
|
||||
|
|
Loading…
Reference in New Issue