Compare commits
No commits in common. "86a9eeaf2ed714897354e04a1cab6e3eaa23a656" and "4f80a0a3e08f09f4f73bd541d43eb9b162e84958" have entirely different histories.
86a9eeaf2e
...
4f80a0a3e0
|
@ -1,15 +1,14 @@
|
||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.bootstrap.Inject;
|
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantList;
|
|
||||||
import ch.zhaw.gartenverwaltung.models.Garden;
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
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;
|
||||||
|
@ -21,20 +20,12 @@ 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;
|
private Crop crop = null;
|
||||||
|
private final PlantListModel plantListModel = new PlantListModel();
|
||||||
@Inject
|
private final GardenSchedule gardenSchedule = new GardenSchedule();
|
||||||
private PlantList plantList;
|
private final Garden garden = new Garden(gardenSchedule);
|
||||||
@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;
|
||||||
|
@ -72,32 +63,33 @@ public class CropDetailController {
|
||||||
@FXML
|
@FXML
|
||||||
private Label spacing_label;
|
private Label spacing_label;
|
||||||
|
|
||||||
|
public CropDetailController() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void editTaskList() {
|
void editTaskList(ActionEvent event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goBack() {
|
void goBack(ActionEvent event) {
|
||||||
Stage stage = (Stage) imageView.getScene().getWindow();
|
Stage stage = (Stage) imageView.getScene().getWindow();
|
||||||
stage.close();
|
stage.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void setArea() {
|
void setArea(ActionEvent event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void setLocation() {
|
void setLocation(ActionEvent event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
|
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException {
|
||||||
this.crop = crop;
|
this.crop = crop;
|
||||||
Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
Plant plant = plantListModel.getFilteredPlantListById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(0);
|
||||||
.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()));
|
||||||
|
@ -112,20 +104,12 @@ public class CropDetailController {
|
||||||
createPestList(plant);
|
createPestList(plant);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTaskLists(Crop crop) {
|
private void createTaskLists(Crop crop) throws IOException {
|
||||||
crop.getCropId().ifPresent(id -> {
|
List<Task> taskList = gardenSchedule.getTaskListForCrop(crop.getCropId().get());
|
||||||
List<Task> taskList;
|
for (Task task : taskList) {
|
||||||
try {
|
Label label = new Label(task.getDescription());
|
||||||
taskList = gardenSchedule.getTaskListForCrop(id);
|
growthPhases_vbox.getChildren().add(label);
|
||||||
for (Task task : taskList) {
|
}
|
||||||
Label label = new Label(task.getDescription());
|
|
||||||
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,7 +1,8 @@
|
||||||
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;
|
||||||
|
@ -9,11 +10,10 @@ 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 {
|
||||||
AppLoader appLoader = new AppLoader();
|
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("MainFXML.fxml"));
|
||||||
|
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,25 +1,28 @@
|
||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.bootstrap.AfterInject;
|
import javafx.event.ActionEvent;
|
||||||
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 {
|
public class MainFXMLController implements Initializable {
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
@ -27,7 +30,7 @@ public class MainFXMLController {
|
||||||
private AnchorPane mainPane;
|
private AnchorPane mainPane;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button myGarden_button;
|
private Button myPlants_button;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button mySchedule_button;
|
private Button mySchedule_button;
|
||||||
|
@ -36,26 +39,26 @@ public class MainFXMLController {
|
||||||
private Button plants_button;
|
private Button plants_button;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToHome() {
|
void goToHome(ActionEvent event) throws IOException {
|
||||||
showPaneAsMainView("Home.fxml");
|
loadPane("Home.fxml");
|
||||||
styleChangeButton(home_button);
|
styleChangeButton(home_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToMyPlants() {
|
void goToMyPlants(ActionEvent event) throws IOException {
|
||||||
showPaneAsMainView("MyGarden.fxml");
|
loadPane("MyPlants.fxml");
|
||||||
styleChangeButton(myGarden_button);
|
styleChangeButton(myPlants_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToMySchedule() {
|
void goToMySchedule(ActionEvent event) throws IOException {
|
||||||
showPaneAsMainView("MySchedule.fxml");
|
loadPane("MySchedule.fxml");
|
||||||
styleChangeButton(mySchedule_button);
|
styleChangeButton(mySchedule_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void goToPlants() {
|
void goToPlants(ActionEvent event) throws IOException {
|
||||||
showPaneAsMainView("Plants.fxml");
|
loadPane("Plants.fxml");
|
||||||
styleChangeButton(plants_button);
|
styleChangeButton(plants_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,27 +67,25 @@ public class MainFXMLController {
|
||||||
* 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 showPaneAsMainView(String fxmlFile) {
|
public void loadPane(String fxmlFile) throws IOException {
|
||||||
try {
|
|
||||||
Pane anchorPane = appLoader.loadPane(fxmlFile);
|
|
||||||
mainPane.getChildren().setAll(anchorPane);
|
|
||||||
anchorPane.prefWidthProperty().bind(mainPane.widthProperty());
|
|
||||||
anchorPane.prefHeightProperty().bind(mainPane.heightProperty());
|
|
||||||
|
|
||||||
anchorPane.removeEventHandler(ChangeViewEvent.CHANGE_MAIN_VIEW, changeMainViewHandler);
|
AnchorPane anchorPane = panes.get(fxmlFile);
|
||||||
anchorPane.addEventHandler(ChangeViewEvent.CHANGE_MAIN_VIEW, changeMainViewHandler);
|
if (anchorPane == null) {
|
||||||
} catch (IOException e) {
|
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
|
||||||
LOG.log(Level.SEVERE, "Could not load pane.", e);
|
anchorPane = loader.load();
|
||||||
|
panes.put(fxmlFile, anchorPane);
|
||||||
|
|
||||||
|
if(fxmlFile.equals("MyPlants.fxml")) {
|
||||||
|
MyPlantsController myPlantsController = loader.getController();
|
||||||
|
myPlantsController.getMainController(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
mainPane.getChildren().setAll(anchorPane);
|
||||||
|
anchorPane.prefWidthProperty().bind(mainPane.widthProperty());
|
||||||
|
anchorPane.prefHeightProperty().bind(mainPane.heightProperty());
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -95,12 +96,10 @@ public class MainFXMLController {
|
||||||
* loads the default FXML File
|
* loads the default FXML File
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@AfterInject
|
@Override
|
||||||
@SuppressWarnings("unused")
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
public void init() {
|
|
||||||
try {
|
try {
|
||||||
preloadPanes();
|
loadPane("Home.fxml");
|
||||||
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);
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
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 | HardinessZoneNotSetException | 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
|
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 GardenSchedule gardenSchedule = new GardenSchedule();
|
||||||
|
private final Garden garden = new Garden(gardenSchedule);
|
||||||
|
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 = garden.getCrops();
|
||||||
|
return cropList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HBox createPlantView(Crop crop) throws HardinessZoneNotSetException, IOException {
|
||||||
|
//ToDo add better design
|
||||||
|
Plant plant = plantListModel.getFilteredPlantListById(Settings.getInstance().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) {
|
||||||
|
garden.removeCrop(crop);
|
||||||
|
loadCropList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
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.models.Garden;
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
||||||
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
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.ListProperty;
|
||||||
import javafx.beans.property.SimpleListProperty;
|
import javafx.beans.property.SimpleListProperty;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
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,22 +20,17 @@ 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.logging.Level;
|
import java.util.ResourceBundle;
|
||||||
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 GardenSchedule gardenSchedule = new GardenSchedule();
|
||||||
@Inject
|
private final Garden garden = new Garden(gardenSchedule);
|
||||||
private GardenSchedule gardenSchedule;
|
private final PlantListModel plantListModel = new PlantListModel();
|
||||||
@Inject
|
|
||||||
private Garden garden;
|
|
||||||
@Inject
|
|
||||||
private PlantList plantList;
|
|
||||||
|
|
||||||
private final ListProperty<Crop> cropListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
private final ListProperty<Crop> cropListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
|
|
||||||
|
@ -87,9 +82,11 @@ public class MyScheduleController {
|
||||||
@FXML
|
@FXML
|
||||||
private ListView<Crop> scheduledPlants_listview;
|
private ListView<Crop> scheduledPlants_listview;
|
||||||
|
|
||||||
@AfterInject
|
public MyScheduleController() throws IOException {
|
||||||
@SuppressWarnings("unused")
|
}
|
||||||
public void init() {
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
List<Crop> cropList;
|
List<Crop> cropList;
|
||||||
try {
|
try {
|
||||||
cropList = garden.getCrops();
|
cropList = garden.getCrops();
|
||||||
|
@ -110,12 +107,15 @@ public class MyScheduleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void lookForSelectedListEntries() {
|
private void lookForSelectedListEntries() {
|
||||||
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Crop>() {
|
||||||
selectedCrop = newValue;
|
@Override
|
||||||
try {
|
public void changed(ObservableValue<? extends Crop> observable, Crop oldValue, Crop newValue) {
|
||||||
loadTaskList();
|
selectedCrop = newValue;
|
||||||
} catch (IOException e) {
|
try {
|
||||||
e.printStackTrace();
|
loadTaskList();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ public class MyScheduleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCellFactoryListView() {
|
private void setCellFactoryListView() {
|
||||||
scheduledPlants_listview.setCellFactory(param -> new ListCell<>() {
|
scheduledPlants_listview.setCellFactory(param -> new ListCell<Crop>() {
|
||||||
@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,12 +141,9 @@ public class MyScheduleController {
|
||||||
setText(null);
|
setText(null);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
String text = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId())
|
setText(plantListModel.getFilteredPlantListById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(0).name());
|
||||||
.map(Plant::name)
|
|
||||||
.orElse("");
|
|
||||||
setText(text);
|
|
||||||
} catch (HardinessZoneNotSetException | IOException e) {
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
LOG.log(Level.WARNING, "Could not get plant for Cell", e);
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +151,7 @@ public class MyScheduleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadTaskList() throws IOException {
|
private void loadTaskList() throws IOException {
|
||||||
List<List<Task>> taskLists;
|
List<List<Task>> taskLists = new LinkedList<>();
|
||||||
if (selectedCrop != null) {
|
if (selectedCrop != null) {
|
||||||
taskLists = gardenSchedule.getTasksUpcomingWeekForCrop(selectedCrop.getCropId().get());
|
taskLists = gardenSchedule.getTasksUpcomingWeekForCrop(selectedCrop.getCropId().get());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,53 +1,44 @@
|
||||||
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.models.Garden;
|
|
||||||
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
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 javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.net.URL;
|
||||||
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 {
|
public class PlantsController implements Initializable {
|
||||||
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;
|
||||||
|
|
||||||
|
@ -71,36 +62,20 @@ public class PlantsController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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() throws IOException {
|
void selectSowDate(ActionEvent event) throws IOException {
|
||||||
|
Parent root;
|
||||||
|
FXMLLoader fxmlLoader = new FXMLLoader(Objects.requireNonNull(getClass().getResource("SelectSowDay.fxml")));
|
||||||
|
root = fxmlLoader.load();
|
||||||
|
SelectSowDayController controller = fxmlLoader.getController();
|
||||||
|
controller.getSelectedPlant(selectedPlant);
|
||||||
Stage stage = new Stage();
|
Stage stage = new Stage();
|
||||||
Dialog<LocalDate> dateSelection = new Dialog<>();
|
stage.setScene(new Scene(root));
|
||||||
dateSelection.setTitle("Select Date");
|
stage.initModality(Modality.APPLICATION_MODAL);
|
||||||
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
stage.setResizable(false);
|
||||||
dateSelection.setResizable(false);
|
stage.showAndWait();
|
||||||
|
|
||||||
DialogPane dialogPane = dateSelection.getDialogPane();
|
|
||||||
|
|
||||||
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
|
||||||
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
|
||||||
|
|
||||||
if (appLoader.loadSceneToStage("SelectSowDay.fxml", stage) instanceof SelectSowDayController controller) {
|
|
||||||
controller.initSaveButton((Button) dialogPane.lookupButton(sowButton));
|
|
||||||
controller.setSelectedPlant(selectedPlant);
|
|
||||||
dateSelection.setResultConverter(button -> button.equals(sowButton) ? controller.retrieveResult() : null);
|
|
||||||
}
|
|
||||||
dialogPane.setContent(stage.getScene().getRoot());
|
|
||||||
|
|
||||||
dateSelection.showAndWait()
|
|
||||||
.ifPresent(date -> {
|
|
||||||
try {
|
|
||||||
garden.plantAsCrop(selectedPlant, date);
|
|
||||||
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
|
||||||
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
|
||||||
}
|
|
||||||
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,9 +85,8 @@ public class PlantsController {
|
||||||
* create event listener for selected list entry and search by query
|
* create event listener for selected list entry and search by query
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@AfterInject
|
@Override
|
||||||
@SuppressWarnings("unused")
|
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||||
public void init() {
|
|
||||||
setListCellFactory();
|
setListCellFactory();
|
||||||
fillPlantListWithHardinessZone();
|
fillPlantListWithHardinessZone();
|
||||||
list_plants.itemsProperty().bind(plantListProperty);
|
list_plants.itemsProperty().bind(plantListProperty);
|
||||||
|
@ -123,7 +97,6 @@ public class PlantsController {
|
||||||
createFilterSeasons();
|
createFilterSeasons();
|
||||||
createFilterHardinessZone();
|
createFilterHardinessZone();
|
||||||
lookForSelectedListEntry();
|
lookForSelectedListEntry();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
viewFilteredListBySearch();
|
viewFilteredListBySearch();
|
||||||
} catch (HardinessZoneNotSetException e) {
|
} catch (HardinessZoneNotSetException e) {
|
||||||
|
@ -134,7 +107,7 @@ public class PlantsController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set text of list view to plant name
|
* set text of list view to plant name
|
||||||
*/
|
*/
|
||||||
private void setListCellFactory() {
|
private void setListCellFactory() {
|
||||||
list_plants.setCellFactory(param -> new ListCell<>() {
|
list_plants.setCellFactory(param -> new ListCell<>() {
|
||||||
|
@ -154,10 +127,9 @@ public class PlantsController {
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
private void viewFilteredListBySeason(Seasons season) throws HardinessZoneNotSetException, IOException {
|
private void viewFilteredListBySeason(Seasons season) throws HardinessZoneNotSetException, IOException {
|
||||||
clearListView();
|
clearListView();
|
||||||
|
@ -167,9 +139,8 @@ public class PlantsController {
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
private void viewFilteredListBySearch() throws HardinessZoneNotSetException, IOException {
|
private void viewFilteredListBySearch() throws HardinessZoneNotSetException, IOException {
|
||||||
search_plants.textProperty().addListener((observable, oldValue, newValue) -> {
|
search_plants.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
@ -214,7 +185,7 @@ public class PlantsController {
|
||||||
for (HardinessZone zone : HardinessZone.values()) {
|
for (HardinessZone zone : HardinessZone.values()) {
|
||||||
RadioButton radioButton = new RadioButton(zone.name());
|
RadioButton radioButton = new RadioButton(zone.name());
|
||||||
radioButton.setToggleGroup(hardinessGroup);
|
radioButton.setToggleGroup(hardinessGroup);
|
||||||
radioButton.setPadding(new Insets(0, 0, 10, 0));
|
radioButton.setPadding(new Insets(0,0,10,0));
|
||||||
if (zone.equals(DEFAULT_HARDINESS_ZONE)) {
|
if (zone.equals(DEFAULT_HARDINESS_ZONE)) {
|
||||||
radioButton.setSelected(true);
|
radioButton.setSelected(true);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +207,7 @@ public class PlantsController {
|
||||||
for (Seasons season : Seasons.values()) {
|
for (Seasons season : Seasons.values()) {
|
||||||
RadioButton radioButton = new RadioButton(season.getName());
|
RadioButton radioButton = new RadioButton(season.getName());
|
||||||
radioButton.setToggleGroup(seasonGroup);
|
radioButton.setToggleGroup(seasonGroup);
|
||||||
radioButton.setPadding(new Insets(0, 0, 10, 0));
|
radioButton.setPadding(new Insets(0,0,10,0));
|
||||||
if (season.equals(Seasons.AllSEASONS)) {
|
if (season.equals(Seasons.AllSEASONS)) {
|
||||||
radioButton.setSelected(true);
|
radioButton.setSelected(true);
|
||||||
}
|
}
|
||||||
|
@ -270,12 +241,12 @@ public class PlantsController {
|
||||||
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
||||||
img_plant.setImage(img);
|
img_plant.setImage(img);
|
||||||
list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
if (newValue != null) {
|
if(newValue != null) {
|
||||||
selectedPlant = newValue;
|
selectedPlant = newValue;
|
||||||
description_plant.setText(selectedPlant.description());
|
description_plant.setText(selectedPlant.description());
|
||||||
selectSowDay_button.setDisable(false);
|
selectSowDay_button.setDisable(false);
|
||||||
Image img1;
|
Image img1;
|
||||||
if (selectedPlant.image() != null) {
|
if(selectedPlant.image() != null) {
|
||||||
img1 = selectedPlant.image();
|
img1 = selectedPlant.image();
|
||||||
} else {
|
} else {
|
||||||
img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
||||||
|
|
|
@ -1,62 +1,101 @@
|
||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
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.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.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
public class SelectSowDayController {
|
public class SelectSowDayController implements Initializable {
|
||||||
private Plant selectedPlant;
|
private Plant selectedPlant = null;
|
||||||
|
private final GardenSchedule gardenSchedule = new GardenSchedule();
|
||||||
|
private final Garden garden = new Garden(gardenSchedule);
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private DatePicker datepicker;
|
private DatePicker datepicker;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private RadioButton harvest_radio;
|
private Label popup_label;
|
||||||
|
|
||||||
public LocalDate retrieveResult() {
|
@FXML
|
||||||
LocalDate sowDate = datepicker.getValue();
|
private Button save_button;
|
||||||
if (harvest_radio.isSelected()) {
|
|
||||||
//ToDo method to get current lifecycle group in plant
|
@FXML
|
||||||
sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
|
private RadioButton sow_radio;
|
||||||
}
|
|
||||||
return sowDate;
|
public SelectSowDayController() throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close the date selector window
|
||||||
|
* @param event event
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
void cancel(ActionEvent event) {
|
||||||
|
closeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link Plant} for which a date should be selected.
|
* get sow date from datePicker or calculate sow date from harvest date
|
||||||
*
|
* 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);
|
||||||
|
}
|
||||||
|
garden.plantAsCrop(selectedPlant, sowDate);
|
||||||
|
closeWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save the plant which will be planted and update label
|
||||||
* @param plant Plant
|
* @param plant Plant
|
||||||
*/
|
*/
|
||||||
public void setSelectedPlant(Plant plant) {
|
public void getSelectedPlant(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
|
||||||
*/
|
*/
|
||||||
@FXML
|
@Override
|
||||||
public void initialize() {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
clearDatePickerEntries();
|
clearDatePickerEntries();
|
||||||
|
|
||||||
Callback<DatePicker, DateCell> dayCellFactory = getDayCellFactory();
|
Callback<DatePicker, DateCell> dayCellFactory= getDayCellFactory();
|
||||||
datepicker.setDayCellFactory(dayCellFactory);
|
datepicker.setDayCellFactory(dayCellFactory);
|
||||||
datepicker.setEditable(false);
|
datepicker.getEditor().setEditable(false);
|
||||||
}
|
|
||||||
|
|
||||||
public void initSaveButton(Button saveButton) {
|
enableDisableSaveButton();
|
||||||
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() {
|
||||||
harvest_radio.selectedProperty().addListener((observable, oldValue, isNowSelected) -> datepicker.setValue(null));
|
sow_radio.selectedProperty().addListener((observable, oldValue, isNowSelected) -> datepicker.getEditor().clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,32 +104,61 @@ public class SelectSowDayController {
|
||||||
*/
|
*/
|
||||||
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
private Callback<DatePicker, DateCell> getDayCellFactory() {
|
||||||
|
|
||||||
return (datePicker) -> new DateCell() {
|
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateItem(LocalDate item, boolean empty) {
|
public DateCell call(final DatePicker datePicker) {
|
||||||
super.updateItem(item, empty);
|
return new DateCell() {
|
||||||
setDisable(true);
|
@Override
|
||||||
setStyle("-fx-background-color: #ffc0cb;");
|
public void updateItem(LocalDate item, boolean empty) {
|
||||||
List<LocalDate> dates;
|
super.updateItem(item, empty);
|
||||||
LocalDate today = LocalDate.now();
|
setDisable(true);
|
||||||
if (harvest_radio.isSelected()) {
|
setStyle("-fx-background-color: #ffc0cb;");
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
|
List<LocalDate> dates;
|
||||||
} else {
|
LocalDate today = LocalDate.now();
|
||||||
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
|
if (sow_radio.isSelected()) {
|
||||||
}
|
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.SOW);
|
||||||
for (LocalDate date : dates) {
|
} else {
|
||||||
if (item.getMonth() == date.getMonth()
|
dates = selectedPlant.getDateListOfGrowthPhase(GrowthPhaseType.HARVEST);
|
||||||
&& item.getDayOfMonth() == date.getDayOfMonth()
|
}
|
||||||
&& item.compareTo(today) > 0) {
|
for (LocalDate date : dates) {
|
||||||
setDisable(false);
|
if (item.getMonth() == date.getMonth()
|
||||||
setStyle("-fx-background-color: #32CD32;");
|
&& item.getDayOfMonth() == date.getDayOfMonth()
|
||||||
|
&& item.compareTo(today) > 0) {
|
||||||
|
setDisable(false);
|
||||||
|
setStyle("-fx-background-color: #32CD32;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!sow_radio.isSelected() && selectedPlant.sowDateFromHarvestDate(item, 0).compareTo(today) < 0)) {
|
||||||
|
setDisable(true);
|
||||||
|
setStyle("-fx-background-color: #ffc0cb;");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
if ((harvest_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((observable, oldValue, newValue) -> {
|
||||||
|
if (newValue == null || newValue.equals("")) {
|
||||||
|
save_button.setDisable(true);
|
||||||
|
} else {
|
||||||
|
save_button.setDisable(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
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 { }
|
|
|
@ -1,138 +0,0 @@
|
||||||
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.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 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;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
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 { }
|
|
|
@ -2,12 +2,12 @@ package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.CropList;
|
import ch.zhaw.gartenverwaltung.io.CropList;
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.JsonCropList;
|
||||||
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 javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
@ -19,25 +19,21 @@ import java.util.Optional;
|
||||||
* The Gardenplan model manages the crops in the gardenplan.
|
* The Gardenplan model manages the crops in the gardenplan.
|
||||||
*/
|
*/
|
||||||
public class Garden {
|
public class Garden {
|
||||||
private final CropList cropList;
|
private CropList cropList;
|
||||||
private final ListProperty<Crop> plantedCrops = new SimpleListProperty<>(FXCollections.observableArrayList());
|
private final ObservableList<Crop> plantedCrops = FXCollections.observableArrayList();
|
||||||
private final GardenSchedule gardenSchedule;
|
private GardenSchedule gardenSchedule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of Gardenplan model
|
* Constructor of Gardenplan model
|
||||||
*
|
*
|
||||||
* @param gardenSchedule holds a reference to the task list object.
|
* @param gardenSchedule holds a reference to the task list object.
|
||||||
*/
|
*/
|
||||||
public Garden(GardenSchedule gardenSchedule, CropList cropList) throws IOException {
|
public Garden(GardenSchedule gardenSchedule) throws IOException {
|
||||||
this.gardenSchedule = gardenSchedule;
|
this.gardenSchedule = gardenSchedule;
|
||||||
this.cropList = cropList;
|
cropList = new JsonCropList();
|
||||||
plantedCrops.addAll(cropList.getCrops());
|
plantedCrops.addAll(cropList.getCrops());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListProperty<Crop> getPlantedCrops() {
|
|
||||||
return plantedCrops;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Crop with a {@link Plant} and the planting date of the plant. Then let the Tasklistmodel create the
|
* Creates a Crop with a {@link Plant} and the planting date of the plant. Then let the Tasklistmodel create the
|
||||||
* gardening {@link Task} for the crop. Store the crop in the gardenplan file and the cache.
|
* gardening {@link Task} for the crop. Store the crop in the gardenplan file and the cache.
|
||||||
|
|
|
@ -12,14 +12,19 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class GardenSchedule {
|
public class GardenSchedule {
|
||||||
private final TaskList taskList;
|
private TaskList taskList;
|
||||||
private final PlantList plantList;
|
private 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 GardenSchedule(){
|
||||||
|
taskList = new JsonTaskList();
|
||||||
|
plantList = new JsonPlantList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create Database Objects.
|
* Constructor to create Database Objects.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ch.zhaw.gartenverwaltung.models;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
||||||
|
import ch.zhaw.gartenverwaltung.io.JsonPlantList;
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantList;
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
import ch.zhaw.gartenverwaltung.types.GrowthPhaseType;
|
||||||
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
||||||
|
@ -15,7 +16,7 @@ import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class PlantListModel {
|
public class PlantListModel {
|
||||||
private final PlantList plantList;
|
private PlantList plantList;
|
||||||
private HardinessZone currentZone;
|
private HardinessZone currentZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,6 +28,11 @@ public class PlantListModel {
|
||||||
/**
|
/**
|
||||||
* Constructor to create Database Object.
|
* Constructor to create Database Object.
|
||||||
*/
|
*/
|
||||||
|
public PlantListModel() {
|
||||||
|
plantList = new JsonPlantList();
|
||||||
|
setDefaultZone();
|
||||||
|
}
|
||||||
|
|
||||||
public PlantListModel(PlantList plantList) {
|
public PlantListModel(PlantList plantList) {
|
||||||
this.plantList = plantList;
|
this.plantList = plantList;
|
||||||
setDefaultZone();
|
setDefaultZone();
|
||||||
|
|
|
@ -9,8 +9,6 @@ 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,8 +11,8 @@
|
||||||
<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="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
<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="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="MySchedule" />
|
||||||
<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>
|
||||||
</HBox>
|
</HBox>
|
||||||
|
|
|
@ -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.MyGardenController" fx:id="myGardenRoot">
|
<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">
|
||||||
<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="My Garden">
|
<Label text="MyPlants">
|
||||||
<font>
|
<font>
|
||||||
<Font name="System Bold" size="28.0" />
|
<Font name="System Bold" size="28.0" />
|
||||||
</font>
|
</font>
|
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
<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,7 +1,9 @@
|
||||||
<?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?>
|
||||||
|
@ -14,11 +16,12 @@
|
||||||
<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" toggleGroup="$group">
|
<RadioButton fx:id="sow_radio" mnemonicParsing="false" selected="true" text="Sow">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
|
@ -35,6 +38,16 @@
|
||||||
<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" />
|
||||||
|
|
|
@ -1,30 +1,24 @@
|
||||||
package ch.zhaw.gartenverwaltung.models;
|
package ch.zhaw.gartenverwaltung.models;
|
||||||
|
|
||||||
import ch.zhaw.gartenverwaltung.io.*;
|
import ch.zhaw.gartenverwaltung.io.*;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
||||||
|
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
|
||||||
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.IOException;
|
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.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.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
public class GardenPlanModelTest {
|
public class GardenPlanModelTest {
|
||||||
private final URL dbDataSource = JsonCropList.class.getResource("user-crops.json");
|
|
||||||
private final URL testFile = JsonCropList.class.getResource("test-user-crops.json");
|
|
||||||
|
|
||||||
CropList cropList;
|
CropList cropList;
|
||||||
List<Crop> exampleCrops;
|
List<Crop> exampleCrops;
|
||||||
Crop exampleCropOnion;
|
Crop exampleCropOnion;
|
||||||
|
@ -37,7 +31,7 @@ public class GardenPlanModelTest {
|
||||||
Garden model;
|
Garden model;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws IOException, URISyntaxException {
|
void setUp() throws IOException {
|
||||||
|
|
||||||
|
|
||||||
examplePlantOnion = new Plant(
|
examplePlantOnion = new Plant(
|
||||||
|
@ -76,7 +70,7 @@ 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,1));
|
exampleCrop3 = new Crop(0,LocalDate.of(2023,3,01));
|
||||||
exampleCrop3.withId(2);
|
exampleCrop3.withId(2);
|
||||||
exampleCrop3.withArea(1.0);
|
exampleCrop3.withArea(1.0);
|
||||||
|
|
||||||
|
@ -84,40 +78,33 @@ public class GardenPlanModelTest {
|
||||||
exampleCrops.add(exampleCrop1);
|
exampleCrops.add(exampleCrop1);
|
||||||
exampleCrops.add(exampleCrop2);
|
exampleCrops.add(exampleCrop2);
|
||||||
exampleCrops.add(exampleCrop3);
|
exampleCrops.add(exampleCrop3);
|
||||||
cropList = mockCropList(exampleCrops);
|
cropList = mockGardenPlan(exampleCrops);
|
||||||
|
|
||||||
// Reset Crop "database" before test
|
GardenSchedule gardenSchedule = new GardenSchedule(new JsonTaskList(), new JsonPlantList());
|
||||||
assertNotNull(testFile);
|
model = new Garden(gardenSchedule);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CropList mockCropList(List<Crop> cropList) throws IOException {
|
CropList mockGardenPlan(List<Crop> cropList) throws IOException {
|
||||||
CropList croplist = mock(CropList.class);
|
CropList gardenPlan = mock(CropList.class);
|
||||||
when(croplist.getCrops()).thenReturn(cropList);
|
when(gardenPlan.getCrops()).thenReturn(cropList);
|
||||||
when(croplist.getCropById(5)).thenReturn(java.util.Optional.ofNullable(exampleCropCarrot));
|
when(gardenPlan.getCropById(5)).thenReturn(java.util.Optional.ofNullable(exampleCropCarrot));
|
||||||
when(croplist.getCropById(3)).thenReturn(java.util.Optional.ofNullable(exampleCropOnion));
|
when(gardenPlan.getCropById(3)).thenReturn(java.util.Optional.ofNullable(exampleCropOnion));
|
||||||
return croplist;
|
return gardenPlan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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));
|
||||||
Optional<Crop> exampleCrop = model.getCrop(2L);
|
exampleCropOnion = model.getCrop(2L).get();
|
||||||
assertTrue(exampleCrop.isPresent());
|
assertEquals(model.getCrops().get(2),exampleCropOnion);
|
||||||
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.5);
|
exampleCrop1.withArea(1.500000);
|
||||||
model.removeCrop(exampleCrop1);
|
model.removeCrop(exampleCrop1);
|
||||||
assertEquals(2,model.getCrops().size());
|
assertEquals(2,model.getCrops().size());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue