Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a69119eb7 | ||
|
|
2f69c48800 | ||
|
|
9ba252b828 | ||
|
|
90d2de65de | ||
|
|
05e7bcc2e8 | ||
|
|
09e582b8a2 | ||
|
|
2b7cec7e6a | ||
|
|
5ef3f6c587 | ||
|
|
15279838b7 | ||
|
|
4f80a0a3e0 | ||
|
|
a5e1acc7c3 | ||
|
|
a8efa8fc2b | ||
|
|
6737e67cda | ||
|
|
a7fa58344c | ||
|
|
6523e1d791 |
@@ -3,6 +3,7 @@ plugins {
|
|||||||
id 'application'
|
id 'application'
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.13'
|
id 'org.openjfx.javafxplugin' version '0.0.13'
|
||||||
id 'org.beryx.jlink' version '2.25.0'
|
id 'org.beryx.jlink' version '2.25.0'
|
||||||
|
id 'jacoco'
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'ch.zhaw.gartenverwaltung'
|
group 'ch.zhaw.gartenverwaltung'
|
||||||
@@ -45,6 +46,15 @@ dependencies {
|
|||||||
|
|
||||||
test {
|
test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
finalizedBy jacocoTestReport
|
||||||
|
}
|
||||||
|
|
||||||
|
jacocoTestReport {
|
||||||
|
dependsOn test
|
||||||
|
}
|
||||||
|
|
||||||
|
jacoco {
|
||||||
|
toolVersion = "0.8.8"
|
||||||
}
|
}
|
||||||
|
|
||||||
jlink {
|
jlink {
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
|
||||||
|
|
||||||
public class Config {
|
|
||||||
private static HardinessZone currentHardinessZone;
|
|
||||||
|
|
||||||
static {
|
|
||||||
currentHardinessZone = HardinessZone.ZONE_8A;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HardinessZone getCurrentHardinessZone() {
|
|
||||||
return currentHardinessZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setCurrentHardinessZone(HardinessZone currentHardinessZone) {
|
|
||||||
Config.currentHardinessZone = currentHardinessZone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,15 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.gardenplan.Gardenplanmodel;
|
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.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.plantList.PlantListModel;
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
import ch.zhaw.gartenverwaltung.types.Crop;
|
||||||
import ch.zhaw.gartenverwaltung.types.Pest;
|
import ch.zhaw.gartenverwaltung.types.Pest;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
@@ -20,12 +21,20 @@ import javafx.stage.Stage;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class CropDetailController {
|
public class CropDetailController {
|
||||||
private Crop crop = null;
|
private Crop crop;
|
||||||
private final PlantListModel plantListModel = new PlantListModel();
|
|
||||||
private final TaskListModel taskListModel = new TaskListModel();
|
@Inject
|
||||||
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
|
private PlantList plantList;
|
||||||
|
@Inject
|
||||||
|
private GardenSchedule gardenSchedule;
|
||||||
|
@Inject
|
||||||
|
private Garden garden;
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName());
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ImageView imageView;
|
private ImageView imageView;
|
||||||
@@ -63,33 +72,33 @@ public class CropDetailController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label spacing_label;
|
private Label spacing_label;
|
||||||
|
|
||||||
public CropDetailController() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void editTaskList(ActionEvent event) {
|
void editTaskList() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goBack(ActionEvent event) {
|
void goBack() {
|
||||||
Stage stage = (Stage) imageView.getScene().getWindow();
|
Stage stage = (Stage) imageView.getScene().getWindow();
|
||||||
stage.close();
|
stage.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void setArea(ActionEvent event) {
|
void setArea() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void setLocation(ActionEvent event) {
|
void setLocation() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException {
|
public void setPlantFromCrop(Crop crop) throws PlantNotFoundException {
|
||||||
this.crop = crop;
|
this.crop = crop;
|
||||||
Plant plant = plantListModel.getFilteredPlantListById(Config.getCurrentHardinessZone(), crop.getPlantId()).get(0);
|
try {
|
||||||
|
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
||||||
|
.orElseThrow(PlantNotFoundException::new);
|
||||||
|
|
||||||
cropName_label.setText(plant.name());
|
cropName_label.setText(plant.name());
|
||||||
description_label.setText(plant.description());
|
description_label.setText(plant.description());
|
||||||
light_label.setText(String.valueOf(plant.light()));
|
light_label.setText(String.valueOf(plant.light()));
|
||||||
@@ -102,14 +111,25 @@ public class CropDetailController {
|
|||||||
location_label.setText("");
|
location_label.setText("");
|
||||||
createTaskLists(crop);
|
createTaskLists(crop);
|
||||||
createPestList(plant);
|
createPestList(plant);
|
||||||
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
|
throw new PlantNotFoundException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTaskLists(Crop crop) throws IOException {
|
private void createTaskLists(Crop crop) {
|
||||||
List<Task> taskList = taskListModel.getTaskListForCrop(crop.getCropId().get());
|
crop.getCropId().ifPresent(id -> {
|
||||||
|
List<Task> taskList;
|
||||||
|
try {
|
||||||
|
taskList = gardenSchedule.getTaskListForCrop(id);
|
||||||
for (Task task : taskList) {
|
for (Task task : taskList) {
|
||||||
Label label = new Label(task.getDescription());
|
Label label = new Label(task.getDescription());
|
||||||
growthPhases_vbox.getChildren().add(label);
|
growthPhases_vbox.getChildren().add(label);
|
||||||
}
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO: Alert
|
||||||
|
LOG.log(Level.SEVERE, "Could not get task list for crop", e.getCause());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPestList(Plant plant) {
|
private void createPestList(Plant plant) {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.bootstrap.AppLoader;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.fxml.FXMLLoader;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,10 +9,11 @@ import java.io.IOException;
|
|||||||
public class HelloApplication extends Application {
|
public class HelloApplication extends Application {
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage stage) throws IOException {
|
public void start(Stage stage) throws IOException {
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("MainFXML.fxml"));
|
AppLoader appLoader = new AppLoader();
|
||||||
Scene scene = new Scene(fxmlLoader.load());
|
|
||||||
|
appLoader.loadSceneToStage("MainFXML.fxml", stage);
|
||||||
|
|
||||||
stage.setTitle("Gartenverwaltung");
|
stage.setTitle("Gartenverwaltung");
|
||||||
stage.setScene(scene);
|
|
||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import javafx.event.ActionEvent;
|
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 javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class MainFXMLController implements Initializable {
|
public class MainFXMLController {
|
||||||
/**
|
|
||||||
* Caching the panes
|
|
||||||
*/
|
|
||||||
private final Map<String, AnchorPane> panes = new HashMap<>();
|
|
||||||
private static final Logger LOG = Logger.getLogger(MainFXMLController.class.getName());
|
private static final Logger LOG = Logger.getLogger(MainFXMLController.class.getName());
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AppLoader appLoader;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button home_button;
|
private Button home_button;
|
||||||
|
|
||||||
@@ -30,7 +27,7 @@ public class MainFXMLController implements Initializable {
|
|||||||
private AnchorPane mainPane;
|
private AnchorPane mainPane;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button myPlants_button;
|
private Button myGarden_button;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button mySchedule_button;
|
private Button mySchedule_button;
|
||||||
@@ -39,26 +36,26 @@ public class MainFXMLController implements Initializable {
|
|||||||
private Button plants_button;
|
private Button plants_button;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToHome(ActionEvent event) throws IOException {
|
void goToHome() {
|
||||||
loadPane("Home.fxml");
|
showPaneAsMainView("Home.fxml");
|
||||||
styleChangeButton(home_button);
|
styleChangeButton(home_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToMyPlants(ActionEvent event) throws IOException {
|
void goToMyPlants() {
|
||||||
loadPane("MyPlants.fxml");
|
showPaneAsMainView("MyGarden.fxml");
|
||||||
styleChangeButton(myPlants_button);
|
styleChangeButton(myGarden_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToMySchedule(ActionEvent event) throws IOException {
|
void goToMySchedule() {
|
||||||
loadPane("MySchedule.fxml");
|
showPaneAsMainView("MySchedule.fxml");
|
||||||
styleChangeButton(mySchedule_button);
|
styleChangeButton(mySchedule_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToPlants(ActionEvent event) throws IOException {
|
void goToPlants() {
|
||||||
loadPane("Plants.fxml");
|
showPaneAsMainView("Plants.fxml");
|
||||||
styleChangeButton(plants_button);
|
styleChangeButton(plants_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,25 +64,27 @@ public class MainFXMLController implements Initializable {
|
|||||||
* set HGrow and VGrow to parent AnchorPane.
|
* set HGrow and VGrow to parent AnchorPane.
|
||||||
* Sends MainController to other Controllers.
|
* Sends MainController to other Controllers.
|
||||||
* @param fxmlFile string of fxml file
|
* @param fxmlFile string of fxml file
|
||||||
* @throws IOException exception when file does not exist
|
|
||||||
*/
|
*/
|
||||||
public void loadPane(String fxmlFile) throws IOException {
|
public void showPaneAsMainView(String fxmlFile) {
|
||||||
|
try {
|
||||||
AnchorPane anchorPane = panes.get(fxmlFile);
|
Pane anchorPane = appLoader.loadPane(fxmlFile);
|
||||||
if (anchorPane == null) {
|
|
||||||
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
|
||||||
anchorPane = loader.load();
|
|
||||||
panes.put(fxmlFile, anchorPane);
|
|
||||||
|
|
||||||
if(fxmlFile.equals("MyPlants.fxml")) {
|
|
||||||
MyPlantsController myPlantsController = loader.getController();
|
|
||||||
myPlantsController.getMainController(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mainPane.getChildren().setAll(anchorPane);
|
mainPane.getChildren().setAll(anchorPane);
|
||||||
anchorPane.prefWidthProperty().bind(mainPane.widthProperty());
|
anchorPane.prefWidthProperty().bind(mainPane.widthProperty());
|
||||||
anchorPane.prefHeightProperty().bind(mainPane.heightProperty());
|
anchorPane.prefHeightProperty().bind(mainPane.heightProperty());
|
||||||
|
|
||||||
|
anchorPane.removeEventHandler(ChangeViewEvent.CHANGE_MAIN_VIEW, changeMainViewHandler);
|
||||||
|
anchorPane.addEventHandler(ChangeViewEvent.CHANGE_MAIN_VIEW, changeMainViewHandler);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, "Could not load pane.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final EventHandler<ChangeViewEvent> changeMainViewHandler = (ChangeViewEvent event) -> showPaneAsMainView(event.view());
|
||||||
|
|
||||||
|
private void preloadPanes() throws IOException {
|
||||||
|
appLoader.loadAndCacheFxml("MyGarden.fxml");
|
||||||
|
appLoader.loadAndCacheFxml("MySchedule.fxml");
|
||||||
|
appLoader.loadAndCacheFxml("Plants.fxml");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void styleChangeButton(Button button) {
|
private void styleChangeButton(Button button) {
|
||||||
@@ -96,10 +95,12 @@ public class MainFXMLController implements Initializable {
|
|||||||
* loads the default FXML File
|
* loads the default FXML File
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@AfterInject
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
@SuppressWarnings("unused")
|
||||||
|
public void init() {
|
||||||
try {
|
try {
|
||||||
loadPane("Home.fxml");
|
preloadPanes();
|
||||||
|
showPaneAsMainView("Home.fxml");
|
||||||
styleChangeButton(home_button);
|
styleChangeButton(home_button);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);
|
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
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.Alert;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.ButtonType;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
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 VBox myPlants_vbox;
|
||||||
|
|
||||||
|
@AfterInject
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void init() {
|
||||||
|
garden.getPlantedCrops().addListener((observable, oldValue, newValue) -> {
|
||||||
|
try {
|
||||||
|
createPlantView(newValue);
|
||||||
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, "Could not update view of croplist!", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
createPlantView(garden.getPlantedCrops());
|
||||||
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, "Could not update view of croplist!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void addPlant() {
|
||||||
|
myGardenRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "Plants.fxml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPlantView(List<Crop> crops) throws HardinessZoneNotSetException, IOException {
|
||||||
|
myPlants_vbox.getChildren().clear();
|
||||||
|
for (Crop crop : crops) {
|
||||||
|
HBox hBox = createPlantView(crop);
|
||||||
|
myPlants_vbox.getChildren().add(hBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HBox createPlantView(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("Details");
|
||||||
|
Button delete = new Button("delete");
|
||||||
|
details.setOnAction(getGoToCropDetailEvent(crop));
|
||||||
|
delete.setOnAction(getDeleteCropEvent(crop));
|
||||||
|
|
||||||
|
hBox.getChildren().addAll(imageView, label, details, delete);
|
||||||
|
return hBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventHandler<ActionEvent> 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventHandler<ActionEvent> getDeleteCropEvent(Crop crop) {
|
||||||
|
return (event) -> {
|
||||||
|
try {
|
||||||
|
showConfirmation(crop);
|
||||||
|
} catch (IOException | HardinessZoneNotSetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showConfirmation(Crop crop) throws IOException, HardinessZoneNotSetException {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setTitle("Delete Crop");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.gardenplan.Gardenplanmodel;
|
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
|
||||||
import ch.zhaw.gartenverwaltung.plantList.PlantListModel;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
|
||||||
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.fxml.FXMLLoader;
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.Parent;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.ButtonType;
|
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.image.ImageView;
|
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.stage.Modality;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class MyPlantsController implements Initializable {
|
|
||||||
MainFXMLController mainController;
|
|
||||||
private final TaskListModel taskListModel = new TaskListModel();
|
|
||||||
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
|
|
||||||
private final PlantListModel plantListModel = new PlantListModel();
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private VBox myPlants_vbox;
|
|
||||||
|
|
||||||
public MyPlantsController() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
void addPlant(ActionEvent event) throws IOException {
|
|
||||||
mainController.loadPane("Plants.fxml");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
|
||||||
//ToDo update, when new crops are added
|
|
||||||
try {
|
|
||||||
loadCropList();
|
|
||||||
} catch (HardinessZoneNotSetException | IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadCropList() throws HardinessZoneNotSetException, IOException {
|
|
||||||
List<Crop> cropList = new LinkedList<>();
|
|
||||||
try {
|
|
||||||
cropList = getCropList();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
createPlantView(cropList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createPlantView(List<Crop> crops) throws HardinessZoneNotSetException, IOException {
|
|
||||||
myPlants_vbox.getChildren().clear();
|
|
||||||
for(Crop crop : crops) {
|
|
||||||
HBox hBox = createPlantView(crop);
|
|
||||||
myPlants_vbox.getChildren().add(hBox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getMainController(MainFXMLController controller) {
|
|
||||||
mainController = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Crop> getCropList() throws IOException {
|
|
||||||
List<Crop> cropList;
|
|
||||||
cropList = gardenplanmodel.getCrops();
|
|
||||||
return cropList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HBox createPlantView(Crop crop) throws HardinessZoneNotSetException, IOException {
|
|
||||||
//ToDo add better design
|
|
||||||
Plant plant = plantListModel.getFilteredPlantListById(Config.getCurrentHardinessZone(), crop.getPlantId()).get(0);
|
|
||||||
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("Details");
|
|
||||||
Button delete = new Button("delete");
|
|
||||||
details.setOnAction(getGoToCropDetailEvent(crop));
|
|
||||||
delete.setOnAction(getDeleteCropEvent(crop));
|
|
||||||
hBox.getChildren().addAll(imageView, label, details, delete);
|
|
||||||
return hBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EventHandler<ActionEvent> getGoToCropDetailEvent(Crop crop) {
|
|
||||||
EventHandler<ActionEvent> event = new EventHandler<ActionEvent>() {
|
|
||||||
@Override
|
|
||||||
public void handle(ActionEvent event) {
|
|
||||||
Parent root;
|
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("CropDetail.fxml")));
|
|
||||||
try {
|
|
||||||
root = fxmlLoader.load();
|
|
||||||
CropDetailController controller = fxmlLoader.getController();
|
|
||||||
controller.setPlantFromCrop(crop);
|
|
||||||
Stage stage = new Stage();
|
|
||||||
stage.setScene(new Scene(root));
|
|
||||||
stage.initModality(Modality.APPLICATION_MODAL);
|
|
||||||
stage.setResizable(true);
|
|
||||||
stage.showAndWait();
|
|
||||||
} catch (IOException | HardinessZoneNotSetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EventHandler<ActionEvent> getDeleteCropEvent(Crop crop) {
|
|
||||||
EventHandler<ActionEvent> event = new EventHandler<ActionEvent>() {
|
|
||||||
@Override
|
|
||||||
public void handle(ActionEvent event) {
|
|
||||||
try {
|
|
||||||
showConfirmation(crop);
|
|
||||||
} catch (IOException | HardinessZoneNotSetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showConfirmation(Crop crop) throws IOException, HardinessZoneNotSetException {
|
|
||||||
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
|
||||||
alert.setTitle("Delete Crop");
|
|
||||||
alert.setHeaderText("Are you sure want to delete this Crop?");
|
|
||||||
alert.setContentText("placeholder");
|
|
||||||
|
|
||||||
Optional<ButtonType> option = alert.showAndWait();
|
|
||||||
|
|
||||||
if (option.get() == ButtonType.OK) {
|
|
||||||
gardenplanmodel.removeCrop(crop);
|
|
||||||
loadCropList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.gardenplan.Gardenplanmodel;
|
import ch.zhaw.gartenverwaltung.bootstrap.AfterInject;
|
||||||
|
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.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.plantList.PlantListModel;
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
import ch.zhaw.gartenverwaltung.types.Crop;
|
||||||
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
import javafx.beans.property.ListProperty;
|
|
||||||
import javafx.beans.property.SimpleListProperty;
|
|
||||||
import javafx.beans.value.ChangeListener;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ListCell;
|
import javafx.scene.control.ListCell;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
@@ -20,19 +17,22 @@ import javafx.scene.layout.Pane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ResourceBundle;
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class MyScheduleController {
|
||||||
|
private static final Logger LOG = Logger.getLogger(MyScheduleController.class.getName());
|
||||||
|
|
||||||
public class MyScheduleController implements Initializable {
|
|
||||||
private Crop selectedCrop = null;
|
private Crop selectedCrop = null;
|
||||||
private final TaskListModel taskListModel = new TaskListModel();
|
|
||||||
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
|
|
||||||
private final PlantListModel plantListModel = new PlantListModel();
|
|
||||||
|
|
||||||
private final ListProperty<Crop> cropListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
@Inject
|
||||||
|
private GardenSchedule gardenSchedule;
|
||||||
|
@Inject
|
||||||
|
private Garden garden;
|
||||||
|
@Inject
|
||||||
|
private PlantList plantList;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label day1_label;
|
private Label day1_label;
|
||||||
@@ -82,20 +82,11 @@ public class MyScheduleController implements Initializable {
|
|||||||
@FXML
|
@FXML
|
||||||
private ListView<Crop> scheduledPlants_listview;
|
private ListView<Crop> scheduledPlants_listview;
|
||||||
|
|
||||||
public MyScheduleController() throws IOException {
|
@AfterInject
|
||||||
}
|
@SuppressWarnings("unused")
|
||||||
|
public void init() {
|
||||||
@Override
|
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
|
||||||
List<Crop> cropList;
|
|
||||||
try {
|
|
||||||
cropList = gardenplanmodel.getCrops();
|
|
||||||
cropListProperty.addAll(cropList);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
setCellFactoryListView();
|
setCellFactoryListView();
|
||||||
scheduledPlants_listview.itemsProperty().bind(cropListProperty);
|
scheduledPlants_listview.itemsProperty().bind(garden.getPlantedCrops());
|
||||||
lookForSelectedListEntries();
|
lookForSelectedListEntries();
|
||||||
setDayLabels();
|
setDayLabels();
|
||||||
information_label.setText("");
|
information_label.setText("");
|
||||||
@@ -107,16 +98,13 @@ public class MyScheduleController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void lookForSelectedListEntries() {
|
private void lookForSelectedListEntries() {
|
||||||
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Crop>() {
|
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
@Override
|
|
||||||
public void changed(ObservableValue<? extends Crop> observable, Crop oldValue, Crop newValue) {
|
|
||||||
selectedCrop = newValue;
|
selectedCrop = newValue;
|
||||||
try {
|
try {
|
||||||
loadTaskList();
|
loadTaskList();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +120,7 @@ public class MyScheduleController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setCellFactoryListView() {
|
private void setCellFactoryListView() {
|
||||||
scheduledPlants_listview.setCellFactory(param -> new ListCell<Crop>() {
|
scheduledPlants_listview.setCellFactory(param -> new ListCell<>() {
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(Crop crop, boolean empty) {
|
protected void updateItem(Crop crop, boolean empty) {
|
||||||
super.updateItem(crop, empty);
|
super.updateItem(crop, empty);
|
||||||
@@ -141,9 +129,12 @@ public class MyScheduleController implements Initializable {
|
|||||||
setText(null);
|
setText(null);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
setText(plantListModel.getFilteredPlantListById(Config.getCurrentHardinessZone(), crop.getPlantId()).get(0).name());
|
String text = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
||||||
|
.map(Plant::name)
|
||||||
|
.orElse("");
|
||||||
|
setText(text);
|
||||||
} catch (HardinessZoneNotSetException | IOException e) {
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
e.printStackTrace();
|
LOG.log(Level.WARNING, "Could not get plant for Cell", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,11 +142,11 @@ public class MyScheduleController implements Initializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadTaskList() throws IOException {
|
private void loadTaskList() throws IOException {
|
||||||
List<List<Task>> taskLists = new LinkedList<>();
|
List<List<Task>> taskLists;
|
||||||
if (selectedCrop != null) {
|
if (selectedCrop != null) {
|
||||||
taskLists = taskListModel.getTasksUpcomingWeekForCrop(selectedCrop.getCropId().get());
|
taskLists = gardenSchedule.getTasksUpcomingWeekForCrop(selectedCrop.getCropId().get());
|
||||||
} else {
|
} else {
|
||||||
taskLists = taskListModel.getTasksUpcomingWeek();
|
taskLists = gardenSchedule.getTasksUpcomingWeek();
|
||||||
}
|
}
|
||||||
if (!taskLists.isEmpty()) {
|
if (!taskLists.isEmpty()) {
|
||||||
viewTaskListOfDay(day1_pane, taskLists.get(0));
|
viewTaskListOfDay(day1_pane, taskLists.get(0));
|
||||||
|
|||||||
@@ -1,44 +1,52 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
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.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.plantList.PlantListModel;
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Seasons;
|
import ch.zhaw.gartenverwaltung.types.Seasons;
|
||||||
import javafx.beans.property.ListProperty;
|
import javafx.beans.property.ListProperty;
|
||||||
import javafx.beans.property.SimpleListProperty;
|
import javafx.beans.property.SimpleListProperty;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.event.ActionEvent;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.Parent;
|
|
||||||
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.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class PlantsController implements Initializable {
|
public class PlantsController {
|
||||||
private static final Logger LOG = Logger.getLogger(PlantsController.class.getName());
|
private static final Logger LOG = Logger.getLogger(PlantsController.class.getName());
|
||||||
private final PlantListModel plantListModel = new PlantListModel();
|
|
||||||
|
@Inject
|
||||||
|
private PlantListModel plantListModel;
|
||||||
|
@Inject
|
||||||
|
private AppLoader appLoader;
|
||||||
|
@Inject
|
||||||
|
private Garden garden;
|
||||||
|
|
||||||
private Plant selectedPlant = null;
|
private Plant selectedPlant = null;
|
||||||
private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A;
|
private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A;
|
||||||
|
|
||||||
// TODO: move to model
|
// TODO: move to model
|
||||||
private final ListProperty<Plant> plantListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
private final ListProperty<Plant> plantListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public AnchorPane plantsRoot;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private VBox seasons;
|
private VBox seasons;
|
||||||
|
|
||||||
@@ -62,20 +70,34 @@ public class PlantsController implements Initializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* open new window to select sow or harvest day to save the crop
|
* open new window to select sow or harvest day to save the crop
|
||||||
* @param event event
|
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
void selectSowDate(ActionEvent event) throws IOException {
|
void selectSowDate() throws IOException {
|
||||||
Parent root;
|
Dialog<LocalDate> dateSelection = new Dialog<>();
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("SelectSowDay.fxml")));
|
dateSelection.setTitle("Select Date");
|
||||||
root = fxmlLoader.load();
|
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
||||||
SelectSowDayController controller = fxmlLoader.getController();
|
dateSelection.setResizable(false);
|
||||||
controller.getSelectedPlant(selectedPlant);
|
|
||||||
Stage stage = new Stage();
|
DialogPane dialogPane = dateSelection.getDialogPane();
|
||||||
stage.setScene(new Scene(root));
|
|
||||||
stage.initModality(Modality.APPLICATION_MODAL);
|
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
||||||
stage.setResizable(false);
|
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
||||||
stage.showAndWait();
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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"));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,8 +107,9 @@ public class PlantsController implements Initializable {
|
|||||||
* create event listener for selected list entry and search by query
|
* create event listener for selected list entry and search by query
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@AfterInject
|
||||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
@SuppressWarnings("unused")
|
||||||
|
public void init() {
|
||||||
setListCellFactory();
|
setListCellFactory();
|
||||||
fillPlantListWithHardinessZone();
|
fillPlantListWithHardinessZone();
|
||||||
list_plants.itemsProperty().bind(plantListProperty);
|
list_plants.itemsProperty().bind(plantListProperty);
|
||||||
@@ -97,6 +120,7 @@ public class PlantsController implements Initializable {
|
|||||||
createFilterSeasons();
|
createFilterSeasons();
|
||||||
createFilterHardinessZone();
|
createFilterHardinessZone();
|
||||||
lookForSelectedListEntry();
|
lookForSelectedListEntry();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
viewFilteredListBySearch();
|
viewFilteredListBySearch();
|
||||||
} catch (HardinessZoneNotSetException e) {
|
} catch (HardinessZoneNotSetException e) {
|
||||||
@@ -127,6 +151,7 @@ public class PlantsController implements Initializable {
|
|||||||
/**
|
/**
|
||||||
* get plant list according to param season and hardiness zone
|
* get plant list according to param season and hardiness zone
|
||||||
* fill list view with plant list
|
* fill list view with plant list
|
||||||
|
*
|
||||||
* @param season enum of seasons
|
* @param season enum of seasons
|
||||||
* @throws HardinessZoneNotSetException throws exception
|
* @throws HardinessZoneNotSetException throws exception
|
||||||
* @throws IOException throws exception
|
* @throws IOException throws exception
|
||||||
@@ -139,6 +164,7 @@ public class PlantsController implements Initializable {
|
|||||||
/**
|
/**
|
||||||
* get plant list filtered by search plant entry and hardiness zone
|
* get plant list filtered by search plant entry and hardiness zone
|
||||||
* fill list view with plant list
|
* fill list view with plant list
|
||||||
|
*
|
||||||
* @throws HardinessZoneNotSetException throws exception when no hardiness zone is defined
|
* @throws HardinessZoneNotSetException throws exception when no hardiness zone is defined
|
||||||
* @throws IOException throws exception
|
* @throws IOException throws exception
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,174 +1,94 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.gardenplan.Gardenplanmodel;
|
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.PlantNotFoundException;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
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.FXML;
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.stage.Stage;
|
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
public class SelectSowDayController implements Initializable {
|
public class SelectSowDayController {
|
||||||
private Plant selectedPlant = null;
|
private Plant selectedPlant;
|
||||||
private final TaskListModel taskListModel = new TaskListModel();
|
|
||||||
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private DatePicker datepicker;
|
private DatePicker datepicker;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label popup_label;
|
private RadioButton harvest_radio;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Button save_button;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private RadioButton sow_radio;
|
private RadioButton sow_radio;
|
||||||
|
|
||||||
public SelectSowDayController() throws IOException {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* close the date selector window
|
|
||||||
* @param event event
|
|
||||||
*/
|
|
||||||
@FXML
|
@FXML
|
||||||
void cancel(ActionEvent event) {
|
public ToggleGroup phase_group;
|
||||||
closeWindow();
|
|
||||||
|
public LocalDate retrieveResult() {
|
||||||
|
LocalDate sowDate = datepicker.getValue();
|
||||||
|
if (harvest_radio.isSelected()) {
|
||||||
|
sowDate = selectedPlant.sowDateFromHarvestDate(sowDate);
|
||||||
|
}
|
||||||
|
return sowDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get sow date from datePicker or calculate sow date from harvest date
|
* Set the {@link Plant} for which a date should be selected.
|
||||||
* save selected plant and sow date
|
*
|
||||||
* @param event event
|
|
||||||
*/
|
|
||||||
@FXML
|
|
||||||
void save(ActionEvent event) throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
|
||||||
LocalDate sowDate;
|
|
||||||
if (sow_radio.isSelected()) {
|
|
||||||
sowDate = datepicker.getValue();
|
|
||||||
} else {
|
|
||||||
//ToDo method to get current lifecycle group in plant
|
|
||||||
sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
|
|
||||||
}
|
|
||||||
gardenplanmodel.plantAsCrop(selectedPlant, sowDate);
|
|
||||||
closeWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* save the plant which will be planted and update label
|
|
||||||
* @param plant Plant
|
* @param plant Plant
|
||||||
*/
|
*/
|
||||||
public void getSelectedPlant(Plant plant) {
|
public void setSelectedPlant(Plant plant) {
|
||||||
selectedPlant = plant;
|
selectedPlant = plant;
|
||||||
popup_label.setText("Select Harvest/Sow Date for" + selectedPlant.name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add listener and set default values
|
* add listener and set default values
|
||||||
* {@inheritDoc}
|
|
||||||
* @param location location
|
|
||||||
* @param resources resources
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@FXML
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize() {
|
||||||
clearDatePickerEntries();
|
clearDatePickerEntries();
|
||||||
|
|
||||||
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
||||||
datepicker.setDayCellFactory(dayCellFactory);
|
datepicker.setDayCellFactory(dayCellFactory);
|
||||||
datepicker.getEditor().setEditable(false);
|
datepicker.setEditable(false);
|
||||||
|
|
||||||
enableDisableSaveButton();
|
sow_radio.setUserData(GrowthPhaseType.SOW);
|
||||||
|
harvest_radio.setUserData(GrowthPhaseType.HARVEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initSaveButton(Button saveButton) {
|
||||||
|
saveButton.disableProperty().bind(datepicker.valueProperty().isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clear date picker editor when radio button is changed
|
* clear date picker editor when radio button is changed
|
||||||
*/
|
*/
|
||||||
private void clearDatePickerEntries() {
|
private void clearDatePickerEntries() {
|
||||||
sow_radio.selectedProperty().addListener(new ChangeListener<Boolean>() {
|
harvest_radio.selectedProperty().addListener((observable, oldValue, isNowSelected) -> datepicker.setValue(null));
|
||||||
@Override
|
|
||||||
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean isNowSelected) {
|
|
||||||
datepicker.getEditor().clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* date picker disable/enable dates according to selected plant: sow or harvest day
|
* date picker disable/enable dates according to selected plant: sow or harvest day
|
||||||
|
*
|
||||||
* @return cellFactory of datePicker
|
* @return cellFactory of datePicker
|
||||||
*/
|
*/
|
||||||
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
||||||
|
|
||||||
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
|
return (datePicker) -> new DateCell() {
|
||||||
|
private final LocalDate today = LocalDate.now();
|
||||||
|
|
||||||
@Override
|
|
||||||
public DateCell call(final DatePicker datePicker) {
|
|
||||||
return new DateCell() {
|
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(LocalDate item, boolean empty) {
|
public void updateItem(LocalDate item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
setDisable(true);
|
setDisable(true);
|
||||||
setStyle("-fx-background-color: #ffc0cb;");
|
setStyle("-fx-background-color: #ffc0cb;");
|
||||||
List<LocalDate> dates;
|
|
||||||
LocalDate today = LocalDate.now();
|
if (item.compareTo(today) > 0 && (!harvest_radio.isSelected() || selectedPlant.sowDateFromHarvestDate(item).compareTo(today) >= 0)) {
|
||||||
if (sow_radio.isSelected()) {
|
GrowthPhaseType selectedPhase = (GrowthPhaseType) phase_group.getSelectedToggle().getUserData();
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
|
|
||||||
} else {
|
if (selectedPlant.isDateInPhase(item, selectedPhase)) {
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
|
|
||||||
}
|
|
||||||
for (LocalDate date : dates) {
|
|
||||||
if (item.getMonth() == date.getMonth()
|
|
||||||
&& item.getDayOfMonth() == date.getDayOfMonth()
|
|
||||||
&& item.compareTo(today) > 0) {
|
|
||||||
setDisable(false);
|
setDisable(false);
|
||||||
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;");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
return dayCellFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* close date picker window
|
|
||||||
*/
|
|
||||||
private void closeWindow() {
|
|
||||||
Stage stage = (Stage) save_button.getScene().getWindow();
|
|
||||||
stage.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* disable save button, when there is no date selected in date picker
|
|
||||||
*/
|
|
||||||
private void enableDisableSaveButton() {
|
|
||||||
save_button.setDisable(true);
|
|
||||||
datepicker.getEditor().textProperty().addListener(new ChangeListener<String>() {
|
|
||||||
@Override
|
|
||||||
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
|
|
||||||
if (newValue == null || newValue.equals("")) {
|
|
||||||
save_button.setDisable(true);
|
|
||||||
} else {
|
|
||||||
save_button.setDisable(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
||||||
|
|
||||||
|
public class Settings {
|
||||||
|
private HardinessZone currentHardinessZone = HardinessZone.ZONE_8A;
|
||||||
|
private static Settings instance;
|
||||||
|
|
||||||
|
static {
|
||||||
|
instance = new Settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Settings getInstance() {
|
||||||
|
return Settings.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Settings() {}
|
||||||
|
|
||||||
|
public HardinessZone getCurrentHardinessZone() {
|
||||||
|
return currentHardinessZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentHardinessZone(HardinessZone currentHardinessZone) {
|
||||||
|
this.currentHardinessZone = currentHardinessZone;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung.bootstrap;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotates a method to be executed after all dependencies annotates with {@link Inject}
|
||||||
|
* have been injected.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface AfterInject { }
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung.bootstrap;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.HelloApplication;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.CropList;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.JsonCropList;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.JsonPlantList;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.JsonTaskList;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.TaskList;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class AppLoader {
|
||||||
|
/**
|
||||||
|
* Caching the panes
|
||||||
|
*/
|
||||||
|
private final Map<String, Pane> panes = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application-wide dependencies
|
||||||
|
*/
|
||||||
|
private final PlantList plantList = new JsonPlantList();
|
||||||
|
private final CropList cropList = new JsonCropList();
|
||||||
|
private final TaskList taskList = new JsonTaskList();
|
||||||
|
|
||||||
|
private final GardenSchedule gardenSchedule = new GardenSchedule(taskList, plantList);
|
||||||
|
private final Garden garden = new Garden(gardenSchedule, cropList);
|
||||||
|
|
||||||
|
|
||||||
|
public AppLoader() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and returns a {@link Pane} (cached).
|
||||||
|
*
|
||||||
|
* @param fxmlFile The file name to be loaded
|
||||||
|
* @return The loaded Pane
|
||||||
|
* @throws IOException if the file could not be loaded
|
||||||
|
*/
|
||||||
|
public Pane loadPane(String fxmlFile) throws IOException {
|
||||||
|
Pane pane = panes.get(fxmlFile);
|
||||||
|
if (pane == null) {
|
||||||
|
loadAndCacheFxml(fxmlFile);
|
||||||
|
pane = panes.get(fxmlFile);
|
||||||
|
}
|
||||||
|
return pane;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given fxml-file from resources (no caching) and creates a new {@link Scene},
|
||||||
|
* which is then appended to the given {@link Stage}.
|
||||||
|
* Performs dependency-injection.
|
||||||
|
*
|
||||||
|
* @param fxmlFile The file name to be loaded
|
||||||
|
* @param appendee The {@link Stage} to which the new {@link Scene} is appended.
|
||||||
|
* @return The controller of the loaded scene.
|
||||||
|
* @throws IOException if the file could not be loaded
|
||||||
|
*/
|
||||||
|
public Object loadSceneToStage(String fxmlFile, Stage appendee) throws IOException {
|
||||||
|
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
||||||
|
Pane root = loader.load();
|
||||||
|
appendee.setScene(new Scene(root));
|
||||||
|
Object controller = loader.getController();
|
||||||
|
annotationInject(controller);
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param fxmlFile The file name to be loaded
|
||||||
|
* @throws IOException if the file could not be loaded
|
||||||
|
*/
|
||||||
|
public void loadAndCacheFxml(String fxmlFile) throws IOException {
|
||||||
|
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
||||||
|
Pane pane = loader.load();
|
||||||
|
panes.put(fxmlFile, pane);
|
||||||
|
annotationInject(loader.getController());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects the applications dependencies into the given object's fields annotated with {@link Inject}.
|
||||||
|
* Afterwards, all methods on the objects annotated with {@link AfterInject} are executed.
|
||||||
|
* (Success of the injections is not guaranteed!)
|
||||||
|
*
|
||||||
|
* @param controller The class containing the injectable fields
|
||||||
|
*/
|
||||||
|
public void annotationInject(Object controller) {
|
||||||
|
Arrays.stream(controller.getClass().getDeclaredFields())
|
||||||
|
.filter(field -> field.isAnnotationPresent(Inject.class))
|
||||||
|
.forEach(field -> {
|
||||||
|
field.setAccessible(true);
|
||||||
|
try {
|
||||||
|
field.set(controller, getAppDependency(field.getType()));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
field.setAccessible(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
Arrays.stream(controller.getClass().getMethods())
|
||||||
|
.filter(method -> method.isAnnotationPresent(AfterInject.class))
|
||||||
|
.forEach(afterInjectMethod -> {
|
||||||
|
if (afterInjectMethod.getParameterCount() == 0) {
|
||||||
|
try {
|
||||||
|
afterInjectMethod.invoke(controller);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getAppDependency(Class<?> type) {
|
||||||
|
return switch (type.getSimpleName()) {
|
||||||
|
case "Garden" -> garden;
|
||||||
|
case "PlantList" -> plantList;
|
||||||
|
case "PlantListModel" -> new PlantListModel(plantList);
|
||||||
|
case "GardenSchedule" -> gardenSchedule;
|
||||||
|
case "AppLoader" -> this;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung.bootstrap;
|
||||||
|
|
||||||
|
import javafx.event.Event;
|
||||||
|
import javafx.event.EventType;
|
||||||
|
|
||||||
|
public class ChangeViewEvent extends Event {
|
||||||
|
private final String view;
|
||||||
|
|
||||||
|
public static final EventType<ChangeViewEvent> CHANGE_MAIN_VIEW = new EventType<>("CHANGE_MAIN_VIEW");
|
||||||
|
|
||||||
|
public ChangeViewEvent(EventType<? extends Event> eventType, String view) {
|
||||||
|
super(eventType);
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String view() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung.bootstrap;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotates a Field to be injected from the application-dependencies
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface Inject { }
|
||||||
+1
-1
@@ -6,7 +6,7 @@ import java.io.IOException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface GardenPlan {
|
public interface CropList {
|
||||||
/**
|
/**
|
||||||
* Yields a list of all {@link Crop}s in the database.
|
* Yields a list of all {@link Crop}s in the database.
|
||||||
*
|
*
|
||||||
+3
-3
@@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class JsonGardenPlan implements GardenPlan {
|
public class JsonCropList implements CropList {
|
||||||
private final URL dataSource;
|
private final URL dataSource;
|
||||||
|
|
||||||
private IdProvider idProvider;
|
private IdProvider idProvider;
|
||||||
@@ -42,7 +42,7 @@ public class JsonGardenPlan implements GardenPlan {
|
|||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
public JsonGardenPlan() {
|
public JsonCropList() {
|
||||||
this.dataSource = getClass().getResource("user-crops.json");
|
this.dataSource = getClass().getResource("user-crops.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public class JsonGardenPlan implements GardenPlan {
|
|||||||
* Constructor to use a specified {@link URL} as a {@link #dataSource}
|
* Constructor to use a specified {@link URL} as a {@link #dataSource}
|
||||||
* @param dataSource A {@link URL} to the file to be used as a data source
|
* @param dataSource A {@link URL} to the file to be used as a data source
|
||||||
*/
|
*/
|
||||||
public JsonGardenPlan(URL dataSource) {
|
public JsonCropList(URL dataSource) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
+4
-4
@@ -20,11 +20,11 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the {@link PlantDatabase} interface for loading {@link Plant} objects
|
* Implements the {@link PlantList} interface for loading {@link Plant} objects
|
||||||
* from a JSON file.
|
* from a JSON file.
|
||||||
* The reads are cached to minimize file-io operations.
|
* The reads are cached to minimize file-io operations.
|
||||||
*/
|
*/
|
||||||
public class JsonPlantDatabase implements PlantDatabase {
|
public class JsonPlantList implements PlantList {
|
||||||
private final URL dataSource = getClass().getResource("plantdb.json");
|
private final URL dataSource = getClass().getResource("plantdb.json");
|
||||||
|
|
||||||
private HardinessZone currentZone;
|
private HardinessZone currentZone;
|
||||||
@@ -49,7 +49,7 @@ public class JsonPlantDatabase implements PlantDatabase {
|
|||||||
* from the {@link #currentZone}, data is loaded from {@link #dataSource}.
|
* from the {@link #currentZone}, data is loaded from {@link #dataSource}.
|
||||||
* In any case, the values of {@link #plantMap} are returned.
|
* In any case, the values of {@link #plantMap} are returned.
|
||||||
*
|
*
|
||||||
* @see PlantDatabase#getPlantList(HardinessZone)
|
* @see PlantList#getPlantList(HardinessZone)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Plant> getPlantList(HardinessZone zone) throws IOException, HardinessZoneNotSetException {
|
public List<Plant> getPlantList(HardinessZone zone) throws IOException, HardinessZoneNotSetException {
|
||||||
@@ -60,7 +60,7 @@ public class JsonPlantDatabase implements PlantDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see PlantDatabase#getPlantById(long)
|
* @see PlantList#getPlantById(long)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Optional<Plant> getPlantById(HardinessZone zone, long id) throws HardinessZoneNotSetException, IOException {
|
public Optional<Plant> getPlantById(HardinessZone zone, long id) throws HardinessZoneNotSetException, IOException {
|
||||||
+5
-6
@@ -1,6 +1,5 @@
|
|||||||
package ch.zhaw.gartenverwaltung.io;
|
package ch.zhaw.gartenverwaltung.io;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||||
@@ -20,11 +19,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the {@link TaskDatabase} interface for loading and writing {@link Task} objects
|
* Implements the {@link TaskList} interface for loading and writing {@link Task} objects
|
||||||
* from and to a JSON file.
|
* from and to a JSON file.
|
||||||
* The reads are cached to minimize file-io operations.
|
* The reads are cached to minimize file-io operations.
|
||||||
*/
|
*/
|
||||||
public class JsonTaskDatabase implements TaskDatabase{
|
public class JsonTaskList implements TaskList {
|
||||||
IdProvider idProvider;
|
IdProvider idProvider;
|
||||||
private final URL dataSource = getClass().getResource("taskdb.json");
|
private final URL dataSource = getClass().getResource("taskdb.json");
|
||||||
private final static String INVALID_DATASOURCE_MSG = "Invalid datasource specified!";
|
private final static String INVALID_DATASOURCE_MSG = "Invalid datasource specified!";
|
||||||
@@ -48,7 +47,7 @@ public class JsonTaskDatabase implements TaskDatabase{
|
|||||||
* If no data is currently loaded, data is loaded from {@link #dataSource}.
|
* If no data is currently loaded, data is loaded from {@link #dataSource}.
|
||||||
* In any case, the values of {@link #taskMap} are returned.
|
* In any case, the values of {@link #taskMap} are returned.
|
||||||
*
|
*
|
||||||
* @see TaskDatabase#getTaskList(LocalDate, LocalDate)
|
* @see TaskList#getTaskList(LocalDate, LocalDate)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Task> getTaskList(LocalDate start, LocalDate end) throws IOException{
|
public List<Task> getTaskList(LocalDate start, LocalDate end) throws IOException{
|
||||||
@@ -90,7 +89,7 @@ public class JsonTaskDatabase implements TaskDatabase{
|
|||||||
* it to the {@link #taskMap}. In any case, the {@link #taskMap} is written
|
* it to the {@link #taskMap}. In any case, the {@link #taskMap} is written
|
||||||
* to the {@link #dataSource}.
|
* to the {@link #dataSource}.
|
||||||
*
|
*
|
||||||
* @see TaskDatabase#saveTask(Task)
|
* @see TaskList#saveTask(Task)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void saveTask(Task task) throws IOException {
|
public void saveTask(Task task) throws IOException {
|
||||||
@@ -108,7 +107,7 @@ public class JsonTaskDatabase implements TaskDatabase{
|
|||||||
* If the {@link Task}s id is found in the {@link #taskMap}, the Task is removed
|
* If the {@link Task}s id is found in the {@link #taskMap}, the Task is removed
|
||||||
* from the {@link #taskMap}. Then the Task are written to the {@link #dataSource}.
|
* from the {@link #taskMap}. Then the Task are written to the {@link #dataSource}.
|
||||||
*
|
*
|
||||||
* @see TaskDatabase#removeTask(Task)
|
* @see TaskList#removeTask(Task)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removeTask(Task task) throws IOException {
|
public void removeTask(Task task) throws IOException {
|
||||||
+1
-1
@@ -11,7 +11,7 @@ import java.util.Optional;
|
|||||||
* A database of {@link Plant}s.
|
* A database of {@link Plant}s.
|
||||||
* The interface specifies the minimal required operations.
|
* The interface specifies the minimal required operations.
|
||||||
*/
|
*/
|
||||||
public interface PlantDatabase {
|
public interface PlantList {
|
||||||
/**
|
/**
|
||||||
* Yields a list of all {@link Plant}s in the database with only data relevant to the specfied {@link HardinessZone}
|
* Yields a list of all {@link Plant}s in the database with only data relevant to the specfied {@link HardinessZone}
|
||||||
*
|
*
|
||||||
+1
-5
@@ -1,20 +1,16 @@
|
|||||||
package ch.zhaw.gartenverwaltung.io;
|
package ch.zhaw.gartenverwaltung.io;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A database of {@link Task}s.
|
* A database of {@link Task}s.
|
||||||
* The interface specifies the minimal required operations.
|
* The interface specifies the minimal required operations.
|
||||||
*/
|
*/
|
||||||
public interface TaskDatabase {
|
public interface TaskList {
|
||||||
/**
|
/**
|
||||||
* Yields a list of all {@link Task}s in the database with the start and end date of a period of time.
|
* Yields a list of all {@link Task}s in the database with the start and end date of a period of time.
|
||||||
*
|
*
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package ch.zhaw.gartenverwaltung.json;
|
package ch.zhaw.gartenverwaltung.json;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantDatabase;
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
@@ -18,7 +18,7 @@ public class PlantImageDeserializer extends JsonDeserializer<Image> {
|
|||||||
@Override
|
@Override
|
||||||
public Image deserialize(JsonParser parser, DeserializationContext context) throws IOException {
|
public Image deserialize(JsonParser parser, DeserializationContext context) throws IOException {
|
||||||
Image result = null;
|
Image result = null;
|
||||||
URL imageUrl = PlantDatabase.class.getResource(String.format("images/%s", parser.getText()));
|
URL imageUrl = PlantList.class.getResource(String.format("images/%s", parser.getText()));
|
||||||
if (imageUrl != null) {
|
if (imageUrl != null) {
|
||||||
try (InputStream is = new FileInputStream(new File(imageUrl.toURI()))) {
|
try (InputStream is = new FileInputStream(new File(imageUrl.toURI()))) {
|
||||||
result = new Image(is);
|
result = new Image(is);
|
||||||
|
|||||||
+28
-29
@@ -1,41 +1,41 @@
|
|||||||
package ch.zhaw.gartenverwaltung.gardenplan;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.GardenPlan;
|
import ch.zhaw.gartenverwaltung.io.CropList;
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.io.JsonGardenPlan;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.PlantNotFoundException;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Crop;
|
import ch.zhaw.gartenverwaltung.types.Crop;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
|
import javafx.beans.property.ListProperty;
|
||||||
|
import javafx.beans.property.SimpleListProperty;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Gardenplan model manages the crops in the gardenplan.
|
* The Gardenplan model manages the crops in the gardenplan.
|
||||||
*/
|
*/
|
||||||
public class Gardenplanmodel {
|
public class Garden {
|
||||||
private GardenPlan gardenPlan;
|
private final CropList cropList;
|
||||||
private List<Crop> cropList;
|
private final ListProperty<Crop> plantedCrops = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
private TaskListModel taskListModel;
|
private final GardenSchedule gardenSchedule;
|
||||||
private Object IllegalArgumentException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of Gardenplan model
|
* Constructor of Gardenplan model
|
||||||
*
|
*
|
||||||
* @param taskListModel holds a reference to the task list object.
|
* @param gardenSchedule holds a reference to the task list object.
|
||||||
*/
|
*/
|
||||||
public Gardenplanmodel(TaskListModel taskListModel) throws IOException {
|
public Garden(GardenSchedule gardenSchedule, CropList cropList) throws IOException {
|
||||||
this.taskListModel = taskListModel;
|
this.gardenSchedule = gardenSchedule;
|
||||||
gardenPlan = new JsonGardenPlan();
|
this.cropList = cropList;
|
||||||
cropList = new ArrayList<>();
|
plantedCrops.addAll(cropList.getCrops());
|
||||||
cropList = gardenPlan.getCrops();
|
}
|
||||||
|
|
||||||
|
public ListProperty<Crop> getPlantedCrops() {
|
||||||
|
return plantedCrops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,9 +52,10 @@ public class Gardenplanmodel {
|
|||||||
Crop crop = new Crop(plant.id(), plantingDate);
|
Crop crop = new Crop(plant.id(), plantingDate);
|
||||||
//TODO Add Area to Plant
|
//TODO Add Area to Plant
|
||||||
//crop.withArea(0);
|
//crop.withArea(0);
|
||||||
gardenPlan.saveCrop(crop);
|
cropList.saveCrop(crop);
|
||||||
taskListModel.planTasksForCrop(crop);
|
gardenSchedule.planTasksForCrop(crop);
|
||||||
cropList = gardenPlan.getCrops();
|
plantedCrops.clear();
|
||||||
|
plantedCrops.addAll(cropList.getCrops());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,9 +65,10 @@ public class Gardenplanmodel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public void removeCrop(Crop crop) throws IOException {
|
public void removeCrop(Crop crop) throws IOException {
|
||||||
gardenPlan.removeCrop(crop);
|
cropList.removeCrop(crop);
|
||||||
taskListModel.removeTasksForCrop(crop.getCropId().orElseThrow(IllegalArgumentException::new));
|
gardenSchedule.removeTasksForCrop(crop.getCropId().orElseThrow(IllegalArgumentException::new));
|
||||||
cropList = gardenPlan.getCrops();
|
plantedCrops.clear();
|
||||||
|
plantedCrops.addAll(cropList.getCrops());
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns a list of {@link Crop}s which are currently in the gardenplan.
|
* Returns a list of {@link Crop}s which are currently in the gardenplan.
|
||||||
@@ -74,10 +76,7 @@ public class Gardenplanmodel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public List<Crop> getCrops() throws IOException {
|
public List<Crop> getCrops() throws IOException {
|
||||||
if(!cropList.isEmpty()){
|
return cropList.getCrops();
|
||||||
cropList = gardenPlan.getCrops();
|
|
||||||
}
|
|
||||||
return cropList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,6 +86,6 @@ public class Gardenplanmodel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public Optional<Crop> getCrop(Long cropId) throws IOException {
|
public Optional<Crop> getCrop(Long cropId) throws IOException {
|
||||||
return gardenPlan.getCropById(cropId);
|
return cropList.getCropById(cropId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-21
@@ -1,6 +1,6 @@
|
|||||||
package ch.zhaw.gartenverwaltung.taskList;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.Config;
|
import ch.zhaw.gartenverwaltung.Settings;
|
||||||
import ch.zhaw.gartenverwaltung.io.*;
|
import ch.zhaw.gartenverwaltung.io.*;
|
||||||
import ch.zhaw.gartenverwaltung.types.*;
|
import ch.zhaw.gartenverwaltung.types.*;
|
||||||
|
|
||||||
@@ -9,29 +9,23 @@ import java.time.LocalDate;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class TaskListModel {
|
public class GardenSchedule {
|
||||||
private TaskDatabase taskDatabase;
|
private final TaskList taskList;
|
||||||
private PlantDatabase plantDatabase;
|
private final PlantList plantList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparators to create sorted Task List
|
* Comparators to create sorted Task List
|
||||||
*/
|
*/
|
||||||
static final Comparator<Task> sortByStartDate = Comparator.comparing(Task::getStartDate);
|
static final Comparator<Task> sortByStartDate = Comparator.comparing(Task::getStartDate);
|
||||||
|
|
||||||
public TaskListModel(){
|
|
||||||
taskDatabase = new JsonTaskDatabase();
|
|
||||||
plantDatabase = new JsonPlantDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create Database Objects.
|
* Constructor to create Database Objects.
|
||||||
*/
|
*/
|
||||||
public TaskListModel(TaskDatabase taskDatabase, PlantDatabase plantDatabase) {
|
public GardenSchedule(TaskList taskList, PlantList plantList) {
|
||||||
this.taskDatabase = taskDatabase;
|
this.taskList = taskList;
|
||||||
this.plantDatabase = plantDatabase;
|
this.plantList = plantList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +34,7 @@ public class TaskListModel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public void addTask(Task task) throws IOException {
|
public void addTask(Task task) throws IOException {
|
||||||
taskDatabase.saveTask(task);
|
taskList.saveTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +45,7 @@ public class TaskListModel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public void planTasksForCrop(Crop crop) throws PlantNotFoundException, HardinessZoneNotSetException, IOException {
|
public void planTasksForCrop(Crop crop) throws PlantNotFoundException, HardinessZoneNotSetException, IOException {
|
||||||
Plant plant = plantDatabase.getPlantById(Config.getCurrentHardinessZone(), crop.getPlantId()).orElseThrow(PlantNotFoundException::new);
|
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).orElseThrow(PlantNotFoundException::new);
|
||||||
for (GrowthPhase growthPhase : plant.lifecycle()) {
|
for (GrowthPhase growthPhase : plant.lifecycle()) {
|
||||||
for (TaskTemplate taskTemplate : growthPhase.taskTemplates()) {
|
for (TaskTemplate taskTemplate : growthPhase.taskTemplates()) {
|
||||||
addTask(taskTemplate.generateTask(crop.getStartDate(), crop.getCropId().orElse(0L)));
|
addTask(taskTemplate.generateTask(crop.getStartDate(), crop.getCropId().orElse(0L)));
|
||||||
@@ -65,7 +59,7 @@ public class TaskListModel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public void removeTasksForCrop(long cropId) throws IOException {
|
public void removeTasksForCrop(long cropId) throws IOException {
|
||||||
taskDatabase.removeTasksForCrop(cropId);
|
taskList.removeTasksForCrop(cropId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +68,7 @@ public class TaskListModel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public void removeTask(Task task) throws IOException {
|
public void removeTask(Task task) throws IOException {
|
||||||
taskDatabase.removeTask(task);
|
taskList.removeTask(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Task> filterListByCrop(List<Task> taskList, Long cropId) {
|
private List<Task> filterListByCrop(List<Task> taskList, Long cropId) {
|
||||||
@@ -144,7 +138,7 @@ public class TaskListModel {
|
|||||||
List<List<Task>> dayTaskList = new ArrayList<>();
|
List<List<Task>> dayTaskList = new ArrayList<>();
|
||||||
for(int i = 0; i < 7; i++) {
|
for(int i = 0; i < 7; i++) {
|
||||||
LocalDate date = LocalDate.now().plusDays(i);
|
LocalDate date = LocalDate.now().plusDays(i);
|
||||||
dayTaskList.add(taskDatabase.getTaskList(date, date));
|
dayTaskList.add(taskList.getTaskList(date, date));
|
||||||
}
|
}
|
||||||
return dayTaskList;
|
return dayTaskList;
|
||||||
}
|
}
|
||||||
@@ -158,7 +152,7 @@ public class TaskListModel {
|
|||||||
List<List<Task>> dayTaskList = new ArrayList<>();
|
List<List<Task>> dayTaskList = new ArrayList<>();
|
||||||
for(int i = 0; i < 7; i++) {
|
for(int i = 0; i < 7; i++) {
|
||||||
LocalDate date = LocalDate.now().plusDays(i);
|
LocalDate date = LocalDate.now().plusDays(i);
|
||||||
dayTaskList.add(filterListByCrop(taskDatabase.getTaskList(date, date), cropId));
|
dayTaskList.add(filterListByCrop(taskList.getTaskList(date, date), cropId));
|
||||||
}
|
}
|
||||||
return dayTaskList;
|
return dayTaskList;
|
||||||
}
|
}
|
||||||
@@ -171,7 +165,7 @@ public class TaskListModel {
|
|||||||
* @throws IOException If the database cannot be accessed
|
* @throws IOException If the database cannot be accessed
|
||||||
*/
|
*/
|
||||||
public List<Task> getFilteredTaskList(LocalDate start, LocalDate end) throws IOException {
|
public List<Task> getFilteredTaskList(LocalDate start, LocalDate end) throws IOException {
|
||||||
return getSortedTaskList(taskDatabase.getTaskList(start, end), sortByStartDate);
|
return getSortedTaskList(taskList.getTaskList(start, end), sortByStartDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
+8
-14
@@ -1,8 +1,7 @@
|
|||||||
package ch.zhaw.gartenverwaltung.plantList;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.io.JsonPlantDatabase;
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantDatabase;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
@@ -16,7 +15,7 @@ import java.util.function.Predicate;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PlantListModel {
|
public class PlantListModel {
|
||||||
private PlantDatabase plantDatabase;
|
private final PlantList plantList;
|
||||||
private HardinessZone currentZone;
|
private HardinessZone currentZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,18 +27,13 @@ public class PlantListModel {
|
|||||||
/**
|
/**
|
||||||
* Constructor to create Database Object.
|
* Constructor to create Database Object.
|
||||||
*/
|
*/
|
||||||
public PlantListModel() {
|
public PlantListModel(PlantList plantList) {
|
||||||
plantDatabase = new JsonPlantDatabase();
|
this.plantList = plantList;
|
||||||
setDefaultZone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlantListModel(PlantDatabase plantDatabase) {
|
|
||||||
this.plantDatabase = plantDatabase;
|
|
||||||
setDefaultZone();
|
setDefaultZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDefaultZone() {
|
private void setDefaultZone() {
|
||||||
currentZone = HardinessZone.ZONE_8A; // TODO: get Default Zone from Config
|
currentZone = HardinessZone.ZONE_8A; // TODO: get Default Zone from Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentZone(HardinessZone currentZone) {
|
public void setCurrentZone(HardinessZone currentZone) {
|
||||||
@@ -72,7 +66,7 @@ public class PlantListModel {
|
|||||||
*/
|
*/
|
||||||
public List<Plant> getSortedPlantList(HardinessZone zone, Comparator<Plant> comparator) throws HardinessZoneNotSetException, IOException {
|
public List<Plant> getSortedPlantList(HardinessZone zone, Comparator<Plant> comparator) throws HardinessZoneNotSetException, IOException {
|
||||||
setCurrentZone(zone);
|
setCurrentZone(zone);
|
||||||
return plantDatabase.getPlantList(zone).stream().sorted(comparator).collect(Collectors.toList());
|
return plantList.getPlantList(zone).stream().sorted(comparator).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,7 +95,7 @@ public class PlantListModel {
|
|||||||
public List<Plant> getFilteredPlantListById(HardinessZone zone, Long id) throws HardinessZoneNotSetException, IOException {
|
public List<Plant> getFilteredPlantListById(HardinessZone zone, Long id) throws HardinessZoneNotSetException, IOException {
|
||||||
setCurrentZone(zone);
|
setCurrentZone(zone);
|
||||||
List<Plant> plantList = new ArrayList<>();
|
List<Plant> plantList = new ArrayList<>();
|
||||||
plantDatabase.getPlantById(zone, id).ifPresent(plantList::add);
|
this.plantList.getPlantById(zone, id).ifPresent(plantList::add);
|
||||||
return plantList;
|
return plantList;
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package ch.zhaw.gartenverwaltung.taskList;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
public class PlantNotFoundException extends Exception {
|
public class PlantNotFoundException extends Exception {
|
||||||
public PlantNotFoundException() {
|
public PlantNotFoundException() {
|
||||||
@@ -3,7 +3,7 @@ package ch.zhaw.gartenverwaltung.types;
|
|||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.LinkedList;
|
import java.time.MonthDay;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -42,11 +42,10 @@ public record Plant(
|
|||||||
/**
|
/**
|
||||||
* get sow date from given harvest day from lifecycle group
|
* get sow date from given harvest day from lifecycle group
|
||||||
* @param harvestDate date of the harvest
|
* @param harvestDate date of the harvest
|
||||||
* @param group lifecycle group
|
|
||||||
* @return LocaleDate of sow date
|
* @return LocaleDate of sow date
|
||||||
*/
|
*/
|
||||||
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate, int group) {
|
public LocalDate sowDateFromHarvestDate(LocalDate harvestDate) {
|
||||||
return harvestDate.minusDays(timeToHarvest(group));
|
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));
|
return (int) DAYS.between(harvest.startDate().atYear(currentYear), sow.startDate().atYear(currentYear));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public int lifecycleGroupFromHarvestDate(LocalDate harvestDate) {
|
||||||
* filter out the given growthPhase out of the lifecycle
|
return lifecycle.stream()
|
||||||
* create list of dates for this growthPhase and return it
|
.filter(growthPhase -> growthPhase.type().equals(GrowthPhaseType.HARVEST) &&
|
||||||
* @param growthPhase the wanted growthPhase
|
dateInRange(harvestDate, growthPhase.startDate(), growthPhase.endDate()))
|
||||||
* @return a list of dates of the current year
|
.map(GrowthPhase::group)
|
||||||
*/
|
.findFirst()
|
||||||
public List<LocalDate> getDateListOfGrowthPhase(GrowthPhaseType growthPhase) {
|
.orElse(0);
|
||||||
List<LocalDate> dates = new LinkedList<>();
|
|
||||||
for (GrowthPhase growth : lifecycle) {
|
|
||||||
if (growth.type().equals(growthPhase)) {
|
|
||||||
dates = addDatesFromMonthDay(growth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* transform monthDay value of the given growthPhase to localDate
|
* Checks if the given {@link LocalDate} is within a {@link GrowthPhase} of the given {@link GrowthPhaseType}
|
||||||
* return a list of dates from start to end of growth phase
|
*
|
||||||
* @param growthPhase the current growthPhase
|
* @param date The date to check.
|
||||||
* @return a list of dates of the current year
|
* @param phase The {@link GrowthPhaseType} to match against
|
||||||
|
* @return Whether the date is within the given {@link GrowthPhaseType}
|
||||||
*/
|
*/
|
||||||
private List<LocalDate> addDatesFromMonthDay(GrowthPhase growthPhase) {
|
public boolean isDateInPhase(LocalDate date, GrowthPhaseType phase) {
|
||||||
List<LocalDate> dates = new LinkedList<>();
|
return lifecycle.stream()
|
||||||
LocalDate today = LocalDate.now();
|
.filter(growthPhase -> growthPhase.type().equals(phase))
|
||||||
LocalDate start = growthPhase.startDate().atYear(today.getYear());
|
.anyMatch(growthPhase -> dateInRange(date, growthPhase.startDate(), growthPhase.endDate()));
|
||||||
LocalDate end = growthPhase.endDate().atYear(today.getYear());
|
|
||||||
while (!start.isAfter(end)) {
|
|
||||||
dates.add(start);
|
|
||||||
start = start.plusDays(1);
|
|
||||||
}
|
}
|
||||||
return dates;
|
|
||||||
|
/**
|
||||||
|
* 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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ module ch.zhaw.gartenverwaltung {
|
|||||||
opens ch.zhaw.gartenverwaltung to javafx.fxml;
|
opens ch.zhaw.gartenverwaltung to javafx.fxml;
|
||||||
opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind;
|
opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind;
|
||||||
exports ch.zhaw.gartenverwaltung;
|
exports ch.zhaw.gartenverwaltung;
|
||||||
|
exports ch.zhaw.gartenverwaltung.io;
|
||||||
exports ch.zhaw.gartenverwaltung.types;
|
exports ch.zhaw.gartenverwaltung.types;
|
||||||
|
exports ch.zhaw.gartenverwaltung.models;
|
||||||
exports ch.zhaw.gartenverwaltung.json;
|
exports ch.zhaw.gartenverwaltung.json;
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<children>
|
<children>
|
||||||
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="121.0" text="Home" HBox.hgrow="NEVER" />
|
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="121.0" text="Home" HBox.hgrow="NEVER" />
|
||||||
<Button fx:id="plants_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToPlants" prefHeight="38.0" prefWidth="121.0" text="Plants" />
|
<Button fx:id="plants_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToPlants" prefHeight="38.0" prefWidth="121.0" text="Plants" />
|
||||||
<Button fx:id="myPlants_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="MyPlants" />
|
<Button fx:id="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
||||||
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
||||||
<Pane maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
<Pane maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
+2
-2
@@ -7,11 +7,11 @@
|
|||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="655.0" prefWidth="1175.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.MyPlantsController">
|
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="655.0" prefWidth="1175.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.MyGardenController" fx:id="myGardenRoot">
|
||||||
<children>
|
<children>
|
||||||
<VBox layoutY="49.0" prefHeight="655.0" prefWidth="1175.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<VBox layoutY="49.0" prefHeight="655.0" prefWidth="1175.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<children>
|
<children>
|
||||||
<Label text="MyPlants">
|
<Label text="My Garden">
|
||||||
<font>
|
<font>
|
||||||
<Font name="System Bold" size="28.0" />
|
<Font name="System Bold" size="28.0" />
|
||||||
</font>
|
</font>
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
|
|
||||||
<AnchorPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="1000.0" prefHeight="853.0"
|
<AnchorPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="1000.0" prefHeight="853.0"
|
||||||
prefWidth="1219.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
|
prefWidth="1219.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
fx:controller="ch.zhaw.gartenverwaltung.PlantsController">
|
fx:controller="ch.zhaw.gartenverwaltung.PlantsController"
|
||||||
|
fx:id="plantsRoot">
|
||||||
<children>
|
<children>
|
||||||
<SplitPane dividerPositions="0.7377363661277062" layoutX="539.0" layoutY="266.0" prefHeight="853.0" prefWidth="1219.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<SplitPane dividerPositions="0.7377363661277062" layoutX="539.0" layoutY="266.0" prefHeight="853.0" prefWidth="1219.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<items>
|
<items>
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
|
||||||
<?import javafx.scene.control.DatePicker?>
|
<?import javafx.scene.control.DatePicker?>
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.control.RadioButton?>
|
<?import javafx.scene.control.RadioButton?>
|
||||||
<?import javafx.scene.control.ToggleGroup?>
|
<?import javafx.scene.control.ToggleGroup?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
@@ -16,20 +14,19 @@
|
|||||||
<children>
|
<children>
|
||||||
<VBox maxWidth="1.7976931348623157E308" prefHeight="408.0" prefWidth="640.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<VBox maxWidth="1.7976931348623157E308" prefHeight="408.0" prefWidth="640.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<children>
|
<children>
|
||||||
<Label fx:id="popup_label" text="Label" />
|
|
||||||
<HBox alignment="CENTER" prefHeight="293.0" prefWidth="631.0">
|
<HBox alignment="CENTER" prefHeight="293.0" prefWidth="631.0">
|
||||||
<children>
|
<children>
|
||||||
<VBox alignment="CENTER_LEFT" prefHeight="88.0" prefWidth="155.0">
|
<VBox alignment="CENTER_LEFT" prefHeight="88.0" prefWidth="155.0">
|
||||||
<children>
|
<children>
|
||||||
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow">
|
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow" toggleGroup="$phase_group">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
<toggleGroup>
|
<toggleGroup>
|
||||||
<ToggleGroup fx:id="group" />
|
<ToggleGroup fx:id="phase_group" />
|
||||||
</toggleGroup>
|
</toggleGroup>
|
||||||
</RadioButton>
|
</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>
|
</children>
|
||||||
<HBox.margin>
|
<HBox.margin>
|
||||||
<Insets top="10.0" />
|
<Insets top="10.0" />
|
||||||
@@ -38,16 +35,6 @@
|
|||||||
<DatePicker fx:id="datepicker" />
|
<DatePicker fx:id="datepicker" />
|
||||||
</children>
|
</children>
|
||||||
</HBox>
|
</HBox>
|
||||||
<HBox fillHeight="false" prefHeight="54.0" prefWidth="631.0" VBox.vgrow="NEVER">
|
|
||||||
<children>
|
|
||||||
<Button fx:id="save_button" mnemonicParsing="false" onAction="#save" prefHeight="25.0" prefWidth="53.0" text="Save">
|
|
||||||
<HBox.margin>
|
|
||||||
<Insets right="10.0" />
|
|
||||||
</HBox.margin>
|
|
||||||
</Button>
|
|
||||||
<Button fx:id="cancel_button" mnemonicParsing="false" onAction="#cancel" text="Cancel" />
|
|
||||||
</children>
|
|
||||||
</HBox>
|
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
|
|||||||
+3
-3
@@ -22,8 +22,8 @@ import java.util.stream.Collectors;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class JsonGardenPlanTest {
|
public class JsonCropListTest {
|
||||||
private GardenPlan testDatabase;
|
private CropList testDatabase;
|
||||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
/**
|
/**
|
||||||
* Files to isolate the test-units
|
* Files to isolate the test-units
|
||||||
@@ -36,7 +36,7 @@ public class JsonGardenPlanTest {
|
|||||||
assertNotNull(testFile);
|
assertNotNull(testFile);
|
||||||
assertNotNull(dbDataSource);
|
assertNotNull(dbDataSource);
|
||||||
Files.copy(Path.of(testFile.toURI()), Path.of(dbDataSource.toURI()), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(Path.of(testFile.toURI()), Path.of(dbDataSource.toURI()), StandardCopyOption.REPLACE_EXISTING);
|
||||||
testDatabase = new JsonGardenPlan(dbDataSource);
|
testDatabase = new JsonCropList(dbDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
+3
-3
@@ -13,12 +13,12 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class JsonPlantDatabaseTest {
|
public class JsonPlantListTest {
|
||||||
PlantDatabase testDatabase;
|
PlantList testDatabase;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void connectToDb() {
|
void connectToDb() {
|
||||||
testDatabase = new JsonPlantDatabase();
|
testDatabase = new JsonPlantList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package ch.zhaw.gartenverwaltung.io;
|
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
public class JsonTaskDatabaseTest {
|
|
||||||
|
|
||||||
TaskDatabase testDatabase;
|
|
||||||
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy");
|
|
||||||
@BeforeEach
|
|
||||||
void connectToDb() {
|
|
||||||
// testDatabase = new JsonTaskDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("Check if results are retrieved completely")
|
|
||||||
void getTasks(){
|
|
||||||
/*
|
|
||||||
List<Task> taskList=null;
|
|
||||||
try {
|
|
||||||
taskList = testDatabase.getTaskList(formatter.parse("01.05.2022"), formatter.parse("01.08.2022"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assertions.assertTrue(taskList.size()>0);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void getTaskForCrop() {
|
|
||||||
// TODO implement Test
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void removeTasksForCrop() {
|
|
||||||
// TODO implement Test
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package ch.zhaw.gartenverwaltung.io;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
public class JsonTaskListTest {
|
||||||
|
|
||||||
|
TaskList testDatabase;
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
|
||||||
|
private final URL dbDataSource = this.getClass().getResource("taskdb.json");
|
||||||
|
private final URL testFile = this.getClass().getResource("test-taskdb.json");
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void connectToDb() throws URISyntaxException, IOException {
|
||||||
|
assertNotNull(testFile);
|
||||||
|
assertNotNull(dbDataSource);
|
||||||
|
Files.copy(Path.of(testFile.toURI()), Path.of(dbDataSource.toURI()), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
testDatabase = new JsonTaskList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Check if results are retrieved completely")
|
||||||
|
void getTasks() {
|
||||||
|
|
||||||
|
List<Task> taskList = null;
|
||||||
|
try {
|
||||||
|
taskList = testDatabase.getTaskList(LocalDate.parse("30.04.2022", formatter),
|
||||||
|
LocalDate.parse("31.05.2022", formatter));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(3, taskList.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled("disabled until adding works.")
|
||||||
|
@Test
|
||||||
|
@DisplayName("Add task.")
|
||||||
|
void addTask() {
|
||||||
|
Task task = new Task("Testtask", "This is a test Task.", LocalDate.parse("01.05.2022", formatter), 1);
|
||||||
|
try {
|
||||||
|
testDatabase.saveTask(task);
|
||||||
|
List<Task> taskList = null;
|
||||||
|
try {
|
||||||
|
taskList = testDatabase.getTaskList(LocalDate.parse("30.04.2022", formatter),
|
||||||
|
LocalDate.parse("31.05.2022", formatter));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(4, taskList.size());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Remove task.")
|
||||||
|
void removeTask() {
|
||||||
|
Task task = new Task("Dummy", "Dummy", LocalDate.parse("31.05.2022", formatter), 1).withId(2);
|
||||||
|
try {
|
||||||
|
testDatabase.removeTask(task);
|
||||||
|
List<Task> taskList = null;
|
||||||
|
|
||||||
|
taskList = testDatabase.getTaskList(LocalDate.parse("30.04.2022", formatter),
|
||||||
|
LocalDate.parse("31.05.2022", formatter));
|
||||||
|
|
||||||
|
Assertions.assertEquals(2, taskList.size());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getTaskForCrop() {
|
||||||
|
List<Task> taskList = null;
|
||||||
|
try {
|
||||||
|
taskList = testDatabase.getTaskForCrop(0);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(6, taskList.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled("Disabled until removing works")
|
||||||
|
@Test
|
||||||
|
void removeTasksForCrop() {
|
||||||
|
List<Task> taskList = null;
|
||||||
|
try {
|
||||||
|
testDatabase.removeTasksForCrop(0);
|
||||||
|
taskList = testDatabase.getTaskForCrop(0);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(0, taskList.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
-27
@@ -1,28 +1,32 @@
|
|||||||
package ch.zhaw.gartenverwaltung.gardenplan;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.*;
|
import ch.zhaw.gartenverwaltung.io.*;
|
||||||
import ch.zhaw.gartenverwaltung.taskList.PlantNotFoundException;
|
|
||||||
import ch.zhaw.gartenverwaltung.taskList.TaskListModel;
|
|
||||||
import ch.zhaw.gartenverwaltung.types.*;
|
import ch.zhaw.gartenverwaltung.types.*;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.MonthDay;
|
import java.time.MonthDay;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
public class GardenPlanModelTest {
|
public class GardenPlanModelTest {
|
||||||
GardenPlan gardenPlan;
|
private final URL dbDataSource = JsonCropList.class.getResource("user-crops.json");
|
||||||
List<Crop> cropList;
|
private final URL testFile = JsonCropList.class.getResource("test-user-crops.json");
|
||||||
|
|
||||||
|
CropList cropList;
|
||||||
|
List<Crop> exampleCrops;
|
||||||
Crop exampleCropOnion;
|
Crop exampleCropOnion;
|
||||||
Crop exampleCropCarrot;
|
Crop exampleCropCarrot;
|
||||||
Crop exampleCrop1;
|
Crop exampleCrop1;
|
||||||
@@ -30,10 +34,10 @@ public class GardenPlanModelTest {
|
|||||||
Crop exampleCrop3;
|
Crop exampleCrop3;
|
||||||
Plant examplePlantOnion;
|
Plant examplePlantOnion;
|
||||||
Plant examplePlantCarrot;
|
Plant examplePlantCarrot;
|
||||||
Gardenplanmodel model;
|
Garden model;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws IOException {
|
void setUp() throws IOException, URISyntaxException {
|
||||||
|
|
||||||
|
|
||||||
examplePlantOnion = new Plant(
|
examplePlantOnion = new Plant(
|
||||||
@@ -72,41 +76,48 @@ public class GardenPlanModelTest {
|
|||||||
exampleCrop2 = new Crop(1,LocalDate.of(2023,3,1));
|
exampleCrop2 = new Crop(1,LocalDate.of(2023,3,1));
|
||||||
exampleCrop2.withId(1);
|
exampleCrop2.withId(1);
|
||||||
exampleCrop2.withArea(0.5);
|
exampleCrop2.withArea(0.5);
|
||||||
exampleCrop3 = new Crop(0,LocalDate.of(2023,3,01));
|
exampleCrop3 = new Crop(0,LocalDate.of(2023,3,1));
|
||||||
exampleCrop3.withId(2);
|
exampleCrop3.withId(2);
|
||||||
exampleCrop3.withArea(1.0);
|
exampleCrop3.withArea(1.0);
|
||||||
|
|
||||||
cropList = new ArrayList<>();
|
exampleCrops = new ArrayList<>();
|
||||||
cropList.add(exampleCrop1);
|
exampleCrops.add(exampleCrop1);
|
||||||
cropList.add(exampleCrop2);
|
exampleCrops.add(exampleCrop2);
|
||||||
cropList.add(exampleCrop3);
|
exampleCrops.add(exampleCrop3);
|
||||||
gardenPlan = mockGardenPlan(cropList);
|
cropList = mockCropList(exampleCrops);
|
||||||
|
|
||||||
TaskListModel taskListModel = new TaskListModel(new JsonTaskDatabase(), new JsonPlantDatabase());
|
// Reset Crop "database" before test
|
||||||
model = new Gardenplanmodel(taskListModel);
|
assertNotNull(testFile);
|
||||||
|
assertNotNull(dbDataSource);
|
||||||
|
Files.copy(Path.of(testFile.toURI()), Path.of(dbDataSource.toURI()), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
CropList testDatabase = new JsonCropList(dbDataSource);
|
||||||
|
|
||||||
|
GardenSchedule gardenSchedule = mock(GardenSchedule.class);
|
||||||
|
model = new Garden(gardenSchedule, testDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
GardenPlan mockGardenPlan(List<Crop> cropList) throws IOException {
|
CropList mockCropList(List<Crop> cropList) throws IOException {
|
||||||
GardenPlan gardenPlan = mock(GardenPlan.class);
|
CropList croplist = mock(CropList.class);
|
||||||
when(gardenPlan.getCrops()).thenReturn(cropList);
|
when(croplist.getCrops()).thenReturn(cropList);
|
||||||
when(gardenPlan.getCropById(5)).thenReturn(java.util.Optional.ofNullable(exampleCropCarrot));
|
when(croplist.getCropById(5)).thenReturn(java.util.Optional.ofNullable(exampleCropCarrot));
|
||||||
when(gardenPlan.getCropById(3)).thenReturn(java.util.Optional.ofNullable(exampleCropOnion));
|
when(croplist.getCropById(3)).thenReturn(java.util.Optional.ofNullable(exampleCropOnion));
|
||||||
return gardenPlan;
|
return croplist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void plantAsCrop() throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
void plantAsCrop() throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
||||||
|
|
||||||
model.plantAsCrop(examplePlantOnion, LocalDate.of(2023,3,1));
|
model.plantAsCrop(examplePlantOnion, LocalDate.of(2023,3,1));
|
||||||
exampleCropOnion = model.getCrop(2L).get();
|
Optional<Crop> exampleCrop = model.getCrop(2L);
|
||||||
assertEquals(model.getCrops().get(2),exampleCropOnion);
|
assertTrue(exampleCrop.isPresent());
|
||||||
|
assertEquals(model.getCrops().get(2), exampleCrop.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void removeCrop() throws IOException {
|
void removeCrop() throws IOException {
|
||||||
exampleCrop1.withId(2);
|
exampleCrop1.withId(2);
|
||||||
exampleCrop1.withArea(1.500000);
|
exampleCrop1.withArea(1.5);
|
||||||
model.removeCrop(exampleCrop1);
|
model.removeCrop(exampleCrop1);
|
||||||
assertEquals(2,model.getCrops().size());
|
assertEquals(2,model.getCrops().size());
|
||||||
}
|
}
|
||||||
+9
-8
@@ -1,8 +1,9 @@
|
|||||||
package ch.zhaw.gartenverwaltung.plantList;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
import ch.zhaw.gartenverwaltung.io.JsonPlantDatabase;
|
import ch.zhaw.gartenverwaltung.io.JsonPlantList;
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantDatabase;
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
import ch.zhaw.gartenverwaltung.types.*;
|
import ch.zhaw.gartenverwaltung.types.*;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@@ -22,15 +23,15 @@ import static org.mockito.Mockito.mock;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
class PlantListModelTest {
|
class PlantListModelTest {
|
||||||
PlantDatabase plantDatabase;
|
PlantList plantList;
|
||||||
List<Plant> examplePlantList;
|
List<Plant> examplePlantList;
|
||||||
PlantListModel model;
|
PlantListModel model;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws HardinessZoneNotSetException, IOException {
|
void setUp() throws HardinessZoneNotSetException, IOException {
|
||||||
createExamplePlantList();
|
createExamplePlantList();
|
||||||
plantDatabase = mockPlantDatabase(examplePlantList);
|
plantList = mockPlantDatabase(examplePlantList);
|
||||||
model = new PlantListModel(plantDatabase);
|
model = new PlantListModel(plantList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
@@ -79,8 +80,8 @@ class PlantListModelTest {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlantDatabase mockPlantDatabase(List<Plant> plantList) throws HardinessZoneNotSetException, IOException {
|
PlantList mockPlantDatabase(List<Plant> plantList) throws HardinessZoneNotSetException, IOException {
|
||||||
PlantDatabase plantDatabase = mock(JsonPlantDatabase.class);
|
PlantList plantDatabase = mock(JsonPlantList.class);
|
||||||
when(plantDatabase.getPlantList(HardinessZone.ZONE_8A)).thenReturn(plantList);
|
when(plantDatabase.getPlantList(HardinessZone.ZONE_8A)).thenReturn(plantList);
|
||||||
when(plantDatabase.getPlantList(HardinessZone.ZONE_1A)).thenReturn(new ArrayList<>());
|
when(plantDatabase.getPlantList(HardinessZone.ZONE_1A)).thenReturn(new ArrayList<>());
|
||||||
when(plantDatabase.getPlantById(HardinessZone.ZONE_8A, 0)).thenReturn(Optional.of(plantList.get(1)));
|
when(plantDatabase.getPlantById(HardinessZone.ZONE_8A, 0)).thenReturn(Optional.of(plantList.get(1)));
|
||||||
+26
-25
@@ -1,6 +1,7 @@
|
|||||||
package ch.zhaw.gartenverwaltung.taskList;
|
package ch.zhaw.gartenverwaltung.taskList;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.*;
|
import ch.zhaw.gartenverwaltung.io.*;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
||||||
import ch.zhaw.gartenverwaltung.types.Plant;
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
||||||
import ch.zhaw.gartenverwaltung.types.Task;
|
import ch.zhaw.gartenverwaltung.types.Task;
|
||||||
@@ -14,47 +15,47 @@ import java.util.*;
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
class TaskListModelTest {
|
class GardenScheduleTest {
|
||||||
TaskDatabase taskDatabase;
|
TaskList taskList;
|
||||||
PlantDatabase plantDatabase;
|
PlantList plantList;
|
||||||
List<Task> exampleTaskList;
|
List<Task> exampleTaskList;
|
||||||
Map<Long, Plant> examplePlantMap;
|
Map<Long, Plant> examplePlantMap;
|
||||||
TaskListModel model;
|
GardenSchedule model;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws IOException {
|
void setUp() throws IOException {
|
||||||
createExampleTaskList();
|
createExampleTaskList();
|
||||||
taskDatabase = mockTaskDatabase(exampleTaskList);
|
taskList = mockTaskDatabase(exampleTaskList);
|
||||||
plantDatabase = mockPlantDatabase(examplePlantMap);
|
plantList = mockPlantDatabase(examplePlantMap);
|
||||||
model = new TaskListModel(taskDatabase, plantDatabase);
|
model = new GardenSchedule(taskList, plantList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskDatabase mockTaskDatabase(List<Task> exampleTaskList) throws IOException {
|
private TaskList mockTaskDatabase(List<Task> exampleTaskList) throws IOException {
|
||||||
TaskDatabase taskDatabase = mock(JsonTaskDatabase.class);
|
TaskList taskList = mock(JsonTaskList.class);
|
||||||
when(taskDatabase.getTaskList(LocalDate.MIN, LocalDate.MAX)).thenReturn(exampleTaskList);
|
when(taskList.getTaskList(LocalDate.MIN, LocalDate.MAX)).thenReturn(exampleTaskList);
|
||||||
|
|
||||||
when(taskDatabase.getTaskList(LocalDate.now(), LocalDate.MAX)).thenReturn((exampleTaskList.subList(1, 4)));
|
when(taskList.getTaskList(LocalDate.now(), LocalDate.MAX)).thenReturn((exampleTaskList.subList(1, 4)));
|
||||||
|
|
||||||
List<Task> pastTasks = new ArrayList<>();
|
List<Task> pastTasks = new ArrayList<>();
|
||||||
pastTasks.add(exampleTaskList.get(0));
|
pastTasks.add(exampleTaskList.get(0));
|
||||||
pastTasks.add(exampleTaskList.get(2));
|
pastTasks.add(exampleTaskList.get(2));
|
||||||
pastTasks.add(exampleTaskList.get(4));
|
pastTasks.add(exampleTaskList.get(4));
|
||||||
when(taskDatabase.getTaskList(LocalDate.MIN, LocalDate.now())).thenReturn(pastTasks);
|
when(taskList.getTaskList(LocalDate.MIN, LocalDate.now())).thenReturn(pastTasks);
|
||||||
|
|
||||||
|
|
||||||
when(taskDatabase.getTaskList(LocalDate.now(), LocalDate.now())).thenReturn(List.of(exampleTaskList.get(2)));
|
when(taskList.getTaskList(LocalDate.now(), LocalDate.now())).thenReturn(List.of(exampleTaskList.get(2)));
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(1L), LocalDate.now().plusDays(1L))).thenReturn(List.of(exampleTaskList.get(1)));
|
when(taskList.getTaskList(LocalDate.now().plusDays(1L), LocalDate.now().plusDays(1L))).thenReturn(List.of(exampleTaskList.get(1)));
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(2L), LocalDate.now().plusDays(2L))).thenReturn(List.of());
|
when(taskList.getTaskList(LocalDate.now().plusDays(2L), LocalDate.now().plusDays(2L))).thenReturn(List.of());
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(3L), LocalDate.now().plusDays(3L))).thenReturn(List.of());
|
when(taskList.getTaskList(LocalDate.now().plusDays(3L), LocalDate.now().plusDays(3L))).thenReturn(List.of());
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(4L), LocalDate.now().plusDays(4L))).thenReturn(List.of());
|
when(taskList.getTaskList(LocalDate.now().plusDays(4L), LocalDate.now().plusDays(4L))).thenReturn(List.of());
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(5L), LocalDate.now().plusDays(5L))).thenReturn(List.of());
|
when(taskList.getTaskList(LocalDate.now().plusDays(5L), LocalDate.now().plusDays(5L))).thenReturn(List.of());
|
||||||
when(taskDatabase.getTaskList(LocalDate.now().plusDays(6L), LocalDate.now().plusDays(6L))).thenReturn(List.of());
|
when(taskList.getTaskList(LocalDate.now().plusDays(6L), LocalDate.now().plusDays(6L))).thenReturn(List.of());
|
||||||
|
|
||||||
return taskDatabase;
|
return taskList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlantDatabase mockPlantDatabase(Map<Long, Plant> examplePlantMap) {
|
private PlantList mockPlantDatabase(Map<Long, Plant> examplePlantMap) {
|
||||||
return new PlantDatabase() {
|
return new PlantList() {
|
||||||
@Override
|
@Override
|
||||||
public List<Plant> getPlantList(HardinessZone zone) {
|
public List<Plant> getPlantList(HardinessZone zone) {
|
||||||
return null;
|
return null;
|
||||||
@@ -86,14 +87,14 @@ class TaskListModelTest {
|
|||||||
void addTask() throws IOException {
|
void addTask() throws IOException {
|
||||||
Task taskToAdd = new Task("name", "description", LocalDate.now(), 1L);
|
Task taskToAdd = new Task("name", "description", LocalDate.now(), 1L);
|
||||||
model.addTask(taskToAdd);
|
model.addTask(taskToAdd);
|
||||||
verify(taskDatabase, times(1)).saveTask(taskToAdd);
|
verify(taskList, times(1)).saveTask(taskToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void removeTask() throws IOException {
|
void removeTask() throws IOException {
|
||||||
Task taskToRemove = new Task("name", "description", LocalDate.now(), 1L);
|
Task taskToRemove = new Task("name", "description", LocalDate.now(), 1L);
|
||||||
model.removeTask(taskToRemove);
|
model.removeTask(taskToRemove);
|
||||||
verify(taskDatabase, times(1)).removeTask(taskToRemove);
|
verify(taskList, times(1)).removeTask(taskToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -153,6 +154,6 @@ class TaskListModelTest {
|
|||||||
@Test
|
@Test
|
||||||
void removeTasksForCrop() throws IOException {
|
void removeTasksForCrop() throws IOException {
|
||||||
model.removeTasksForCrop(1L);
|
model.removeTasksForCrop(1L);
|
||||||
verify(taskDatabase, times(1)).removeTasksForCrop(1L);
|
verify(taskList, times(1)).removeTasksForCrop(1L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id" : 1,
|
||||||
|
"name" : "sow plant",
|
||||||
|
"description": "Plant the seeds, crops in de bed.",
|
||||||
|
"startDate" : "2022-05-01",
|
||||||
|
"endDate" : "2022-05-01",
|
||||||
|
"interval" : 0,
|
||||||
|
"cropId" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : 2,
|
||||||
|
"name" : "water plant",
|
||||||
|
"description": "water the plant, so that the soil is wet around the plant.",
|
||||||
|
"startDate" : "2022-05-01",
|
||||||
|
"endDate" : "2022-09-01",
|
||||||
|
"interval" : 2,
|
||||||
|
"cropId" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : 3,
|
||||||
|
"name" : "fertilize plant",
|
||||||
|
"description": "The fertilizer has to be mixed with water. Then fertilize the plants soil with the mixture",
|
||||||
|
"startDate" : "2022-06-01",
|
||||||
|
"endDate" : "2022-08-01",
|
||||||
|
"interval" : 28,
|
||||||
|
"cropId" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : 4,
|
||||||
|
"name" : "covering plant",
|
||||||
|
"description": "Take a big enough coverage for the plants. Cover the whole plant with a bit space between the plant and the coverage",
|
||||||
|
"startDate" : "2022-07-01",
|
||||||
|
"endDate" : "2022-07-01",
|
||||||
|
"interval" : 0,
|
||||||
|
"cropId" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : 5,
|
||||||
|
"name" : "look after plant",
|
||||||
|
"description": "Look for pest or illness at the leaves of the plant. Check the soil around the plant, if the roots are enough covered with soil",
|
||||||
|
"startDate" : "2022-05-01",
|
||||||
|
"endDate" : "2022-09-01",
|
||||||
|
"interval" : 5,
|
||||||
|
"cropId" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id" : 6,
|
||||||
|
"name" : "harvest plant",
|
||||||
|
"description": "Pull the ripe vegetables out from the soil. Clean them with clear, fresh water. ",
|
||||||
|
"startDate" : "2022-09-01",
|
||||||
|
"endDate" : "2022-09-01",
|
||||||
|
"interval" : 0,
|
||||||
|
"cropId" : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user