Compare commits

...

12 Commits

Author SHA1 Message Date
Roman Schenk bee517317a Merge pull request #57 from schrom01/feature_cropsAndTaskGUI_M2
Feature crops and task gui m2
2022-11-11 12:28:17 +01:00
giavaphi 2be9df6094 Merge branch 'dev' into feature_cropsAndTaskGUI_M2 2022-11-11 12:21:05 +01:00
Roman Schenk 5faf61089a Merge pull request #56 from schrom01/feature_logger_M2
Include Logger
2022-11-11 12:19:04 +01:00
giavaphi 8e23124c6b display List of Crops, get detail of crop and display taskList 2022-11-10 22:50:49 +01:00
giavaphi 0e40bc6304 Merge remote-tracking branch 'origin/feature_cropsAndTaskGUI_M2' into feature_cropsAndTaskGUI_M2
# Conflicts:
#	src/main/java/ch/zhaw/gartenverwaltung/CropDetailController.java
#	src/main/java/ch/zhaw/gartenverwaltung/MyPlantsController.java
#	src/main/java/ch/zhaw/gartenverwaltung/MyScheduleController.java
#	src/main/resources/ch/zhaw/gartenverwaltung/CropDetail.fxml
2022-11-08 21:08:23 +01:00
giavaphi ced2645bd7 connection task list model and garden plan model with controllers 2022-11-08 21:03:01 +01:00
giavaphi 802f238d69 gui details of crop basics 2022-11-08 19:26:08 +01:00
giavaphi 096abfd148 #48 and #47 basics of gui 2022-11-08 19:26:08 +01:00
David Guler 590049b9cf feat: Added logging and refactored code to accommodate 2022-11-08 07:36:31 +01:00
David Guler ad05e9e95a refactor: remove exception-based control-flow 2022-11-08 07:31:04 +01:00
giavaphi ea4a1ecc6a gui details of crop basics 2022-11-06 17:46:35 +01:00
giavaphi 3077e02b32 #48 and #47 basics of gui 2022-11-05 23:50:45 +01:00
16 changed files with 568 additions and 124 deletions

View File

@ -0,0 +1,132 @@
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.Pest;
import ch.zhaw.gartenverwaltung.types.Plant;
import ch.zhaw.gartenverwaltung.types.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.List;
public class CropDetailController {
private Crop crop = null;
private final PlantListModel plantListModel = new PlantListModel();
private final TaskListModel taskListModel = new TaskListModel();
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
@FXML
private ImageView imageView;
@FXML
private Button area_button;
@FXML
private Label area_label;
@FXML
private Label cropName_label;
@FXML
private Label description_label;
@FXML
private VBox growthPhases_vbox;
@FXML
private Label location_label;
@FXML
private Label light_label;
@FXML
private Button location_button;
@FXML
private VBox pests_vbox;
@FXML
private Label soil_label;
@FXML
private Label spacing_label;
public CropDetailController() throws IOException {
}
@FXML
void editTaskList(ActionEvent event) {
}
@FXML
void goBack(ActionEvent event) {
Stage stage = (Stage) imageView.getScene().getWindow();
stage.close();
}
@FXML
void setArea(ActionEvent event) {
}
@FXML
void setLocation(ActionEvent event) {
}
public void setPlantFromCrop(Crop crop) throws HardinessZoneNotSetException, IOException {
this.crop = crop;
Plant plant = plantListModel.getFilteredPlantListById(Config.getCurrentHardinessZone(), crop.getPlantId()).get(0);
cropName_label.setText(plant.name());
description_label.setText(plant.description());
light_label.setText(String.valueOf(plant.light()));
soil_label.setText(plant.soil());
spacing_label.setText(plant.spacing());
if (plant.image() != null) {
imageView.setImage(plant.image());
}
area_label.setText("");
location_label.setText("");
createTaskLists(crop);
createPestList(plant);
}
private void createTaskLists(Crop crop) throws IOException {
List<Task> taskList = taskListModel.getTaskListForCrop(crop.getCropId().get());
for (Task task : taskList) {
Label label = new Label(task.getDescription());
growthPhases_vbox.getChildren().add(label);
}
}
private void createPestList(Plant plant) {
List<Pest> pests = plant.pests();
for (Pest pest : pests) {
Label label = new Label(pest.name() + ":");
label.setStyle("-fx-font-weight: bold");
HBox hBox = new HBox();
hBox.fillHeightProperty();
Label label1 = new Label(pest.description());
label1.setAlignment(Pos.TOP_LEFT);
label1.setWrapText(true);
label1.setMaxWidth(600);
label1.setMaxHeight(100);
Button button = new Button("Get Counter Measures");
hBox.getChildren().addAll(label1, button);
pests_vbox.getChildren().addAll(label, hBox);
}
}
}

View File

@ -4,7 +4,6 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
@ -14,12 +13,15 @@ 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.Logger;
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());
@FXML
private Button home_button;
@ -100,7 +102,7 @@ public class MainFXMLController implements Initializable {
loadPane("Home.fxml");
styleChangeButton(home_button);
} catch (IOException e) {
e.printStackTrace();
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);
}
}
}

View File

@ -1,27 +1,45 @@
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.LinkedList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.*;
public class MyPlantsController implements Initializable {
MainFXMLController mainController;
@FXML
private Button addPlant_button;
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");
@ -29,15 +47,29 @@ public class MyPlantsController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
//ToDo
List<Plant> myPlants = getMyPlants();
createPlantView(myPlants);
//ToDo update, when new crops are added
try {
loadCropList();
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
}
}
private void createPlantView(List<Plant> myPlants) {
//ToDo
for(Plant plant : myPlants) {
createPlantView();
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);
}
}
@ -45,14 +77,84 @@ public class MyPlantsController implements Initializable {
mainController = controller;
}
private List<Plant> getMyPlants() {
//ToDo method to get myPlantList(scheduled)
//Method to call all Plants saved
List<Plant> myPlantList = new LinkedList<>();
return myPlantList;
private List<Crop> getCropList() throws IOException {
List<Crop> cropList;
cropList = gardenplanmodel.getCrops();
return cropList;
}
private void createPlantView() {
//ToDo FXML Panel with Plant data
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();
}
}
}

View File

@ -1,15 +1,25 @@
package ch.zhaw.gartenverwaltung;
import ch.zhaw.gartenverwaltung.types.Plant;
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.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.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.util.LinkedList;
@ -17,7 +27,12 @@ import java.util.List;
import java.util.ResourceBundle;
public class MyScheduleController implements Initializable {
private Plant selectedPlant = 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());
@FXML
private Label day1_label;
@ -65,27 +80,41 @@ public class MyScheduleController implements Initializable {
private Label information_label;
@FXML
private ListView<Plant> scheduledPlants_listview;
private ListView<Crop> scheduledPlants_listview;
public MyScheduleController() throws IOException {
}
@Override
public void initialize(URL location, ResourceBundle resources) {
List<Plant> plantList = new LinkedList<>();
fillListViewMyPlantsInSchedule(plantList);
getSelectedPlantTask();
List<Crop> cropList;
try {
cropList = gardenplanmodel.getCrops();
cropListProperty.addAll(cropList);
} catch (IOException e) {
e.printStackTrace();
}
setCellFactoryListView();
scheduledPlants_listview.itemsProperty().bind(cropListProperty);
lookForSelectedListEntries();
setDayLabels();
information_label.setText("");
try {
loadTaskList();
} catch (IOException e) {
e.printStackTrace();
}
}
private void getSelectedPlantTask() {
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Plant>() {
private void lookForSelectedListEntries() {
scheduledPlants_listview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Crop>() {
@Override
public void changed(ObservableValue<? extends Plant> observable, Plant oldValue, Plant newValue) {
if(newValue != null) {
selectedPlant = newValue;
//ToDo update day<x>_panel with task for the day
} else {
selectedPlant = null;
//ToDo update day<x>_panel with task for the day (all plants)
public void changed(ObservableValue<? extends Crop> observable, Crop oldValue, Crop newValue) {
selectedCrop = newValue;
try {
loadTaskList();
} catch (IOException e) {
e.printStackTrace();
}
}
});
@ -102,23 +131,52 @@ public class MyScheduleController implements Initializable {
day7_label.setText(today.plusDays(6).getDayOfWeek().toString());
}
private void fillListViewMyPlantsInSchedule(List<Plant> list) {
for (Plant plant : list) {
scheduledPlants_listview.getItems().add(plant);
}
scheduledPlants_listview.setCellFactory(param -> new ListCell<Plant>() {
private void setCellFactoryListView() {
scheduledPlants_listview.setCellFactory(param -> new ListCell<Crop>() {
@Override
protected void updateItem(Plant plant, boolean empty) {
super.updateItem(plant, empty);
protected void updateItem(Crop crop, boolean empty) {
super.updateItem(crop, empty);
if (empty || plant == null || plant.name() == null) {
if (empty || crop == null) {
setText(null);
} else {
setText(plant.name());
try {
setText(plantListModel.getFilteredPlantListById(Config.getCurrentHardinessZone(), crop.getPlantId()).get(0).name());
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
}
}
}
});
}
private void loadTaskList() throws IOException {
List<List<Task>> taskLists = new LinkedList<>();
if (selectedCrop != null) {
taskLists = taskListModel.getTasksUpcomingWeekForCrop(selectedCrop.getCropId().get());
} else {
taskLists = taskListModel.getTasksUpcomingWeek();
}
if (!taskLists.isEmpty()) {
viewTaskListOfDay(day1_pane, taskLists.get(0));
viewTaskListOfDay(day2_pane, taskLists.get(1));
viewTaskListOfDay(day3_pane, taskLists.get(2));
viewTaskListOfDay(day4_pane, taskLists.get(3));
viewTaskListOfDay(day5_pane, taskLists.get(4));
viewTaskListOfDay(day6_pane, taskLists.get(5));
viewTaskListOfDay(day7_pane, taskLists.get(6));
}
}
private void viewTaskListOfDay(Pane pane, List<Task> tasks) {
//ToDo update pane with task list
VBox vBox = new VBox();
for (Task task : tasks) {
Label label = new Label(task.getDescription());
vBox.getChildren().add(label);
}
pane.getChildren().add(vBox);
}
}

View File

@ -7,8 +7,6 @@ import ch.zhaw.gartenverwaltung.types.Plant;
import ch.zhaw.gartenverwaltung.types.Seasons;
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.event.ActionEvent;
import javafx.fxml.FXML;
@ -29,8 +27,11 @@ import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PlantsController implements Initializable {
private static final Logger LOG = Logger.getLogger(PlantsController.class.getName());
private final PlantListModel plantListModel = new PlantListModel();
private Plant selectedPlant = null;
private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A;
@ -98,8 +99,10 @@ public class PlantsController implements Initializable {
lookForSelectedListEntry();
try {
viewFilteredListBySearch();
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
} catch (HardinessZoneNotSetException e) {
LOG.log(Level.WARNING, "Hardiness Zone not set!");
} catch (IOException e) {
LOG.log(Level.WARNING, "Could not retrieve data!", e);
}
}
@ -107,7 +110,7 @@ public class PlantsController implements Initializable {
* set text of list view to plant name
*/
private void setListCellFactory() {
list_plants.setCellFactory(param -> new ListCell<Plant>() {
list_plants.setCellFactory(param -> new ListCell<>() {
@Override
protected void updateItem(Plant plant, boolean empty) {
super.updateItem(plant, empty);
@ -143,13 +146,15 @@ public class PlantsController implements Initializable {
search_plants.textProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.isEmpty()) {
fillPlantListWithHardinessZone();
}else {
} else {
try {
List<Plant> filteredPlants = plantListModel.getFilteredPlantListByString(DEFAULT_HARDINESS_ZONE, newValue);
clearListView();
plantListProperty.addAll(filteredPlants);
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
} catch (HardinessZoneNotSetException e) {
LOG.log(Level.WARNING, "Hardiness Zone not set!");
} catch (IOException e) {
LOG.log(Level.WARNING, "Could not retrieve data!", e);
}
}
});
@ -163,8 +168,10 @@ public class PlantsController implements Initializable {
try {
clearListView();
plantListProperty.addAll(plantListModel.getPlantList(plantListModel.getCurrentZone()));
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
} catch (HardinessZoneNotSetException e) {
LOG.log(Level.WARNING, "Hardiness Zone not set!");
} catch (IOException e) {
LOG.log(Level.WARNING, "Could not retrieve data!", e);
}
}
@ -182,12 +189,9 @@ public class PlantsController implements Initializable {
if (zone.equals(DEFAULT_HARDINESS_ZONE)) {
radioButton.setSelected(true);
}
radioButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
plantListModel.setCurrentZone(zone);
fillPlantListWithHardinessZone();
}
radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> {
plantListModel.setCurrentZone(zone);
fillPlantListWithHardinessZone();
});
climate_zones.getChildren().add(radioButton);
}
@ -207,20 +211,19 @@ public class PlantsController implements Initializable {
if (season.equals(Seasons.AllSEASONS)) {
radioButton.setSelected(true);
}
radioButton.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (season.equals(Seasons.AllSEASONS)) {
fillPlantListWithHardinessZone();
} else {
try {
viewFilteredListBySeason(season);
} catch (HardinessZoneNotSetException | IOException e) {
e.printStackTrace();
}
radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (season.equals(Seasons.AllSEASONS)) {
fillPlantListWithHardinessZone();
} else {
try {
viewFilteredListBySeason(season);
} catch (HardinessZoneNotSetException e) {
LOG.log(Level.WARNING, "Hardiness Zone not set!");
} catch (IOException e) {
LOG.log(Level.WARNING, "Could not retrieve data!", e);
}
}
});
seasons.getChildren().add(radioButton);
}
@ -237,27 +240,24 @@ public class PlantsController implements Initializable {
selectSowDay_button.setDisable(true);
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
img_plant.setImage(img);
list_plants.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Plant>() {
@Override
public void changed(ObservableValue<? extends Plant> observable, Plant oldValue, Plant newValue) {
if(newValue != null) {
selectedPlant = newValue;
description_plant.setText(selectedPlant.description());
selectSowDay_button.setDisable(false);
Image img;
if(selectedPlant.image() != null) {
img = selectedPlant.image();
} else {
img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
}
img_plant.setImage(img);
list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if(newValue != null) {
selectedPlant = newValue;
description_plant.setText(selectedPlant.description());
selectSowDay_button.setDisable(false);
Image img1;
if(selectedPlant.image() != null) {
img1 = selectedPlant.image();
} else {
selectedPlant = null;
description_plant.setText("");
selectSowDay_button.setDisable(true);
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
img_plant.setImage(img);
img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
}
img_plant.setImage(img1);
} else {
selectedPlant = null;
description_plant.setText("");
selectSowDay_button.setDisable(true);
Image img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
img_plant.setImage(img1);
}
});
}

View File

@ -1,5 +1,9 @@
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.Plant;
import javafx.beans.value.ChangeListener;
@ -11,6 +15,7 @@ import javafx.scene.control.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDate;
import java.util.List;
@ -18,6 +23,8 @@ import java.util.ResourceBundle;
public class SelectSowDayController implements Initializable {
private Plant selectedPlant = null;
private final TaskListModel taskListModel = new TaskListModel();
private final Gardenplanmodel gardenplanmodel = new Gardenplanmodel(taskListModel);
@FXML
private DatePicker datepicker;
@ -31,6 +38,8 @@ public class SelectSowDayController implements Initializable {
@FXML
private RadioButton sow_radio;
public SelectSowDayController() throws IOException {}
/**
* close the date selector window
* @param event event
@ -46,8 +55,7 @@ public class SelectSowDayController implements Initializable {
* @param event event
*/
@FXML
void save(ActionEvent event) {
//ToDo save plant and sow date to crop/gardenplan model
void save(ActionEvent event) throws HardinessZoneNotSetException, IOException, PlantNotFoundException {
LocalDate sowDate;
if (sow_radio.isSelected()) {
sowDate = datepicker.getValue();
@ -55,8 +63,7 @@ public class SelectSowDayController implements Initializable {
//ToDo method to get current lifecycle group in plant
sowDate = selectedPlant.sowDateFromHarvestDate(datepicker.getValue(), 0);
}
System.out.println(sowDate);
System.out.println(selectedPlant);
gardenplanmodel.plantAsCrop(selectedPlant, sowDate);
closeWindow();
}

View File

@ -145,7 +145,6 @@ public class JsonGardenPlan implements GardenPlan {
.registerModule(new Jdk8Module())
.writeValue(new File(dataSource.toURI()), cropMap.values());
} catch (URISyntaxException e) {
// TODO: Log
throw new IOException(INVALID_DATASOURCE_MSG, e);
}
}

View File

@ -16,13 +16,12 @@ public class GrowthPhaseTypeDeserializer extends StdDeserializer<GrowthPhaseType
@Override
public GrowthPhaseType deserialize(JsonParser parser, DeserializationContext context) throws IOException {
GrowthPhaseType result = null;
GrowthPhaseType result;
String token = parser.getText();
try {
result = GrowthPhaseType.valueOf(token.toUpperCase());
} catch (IllegalArgumentException e) {
// TODO: Log
System.err.printf("Bad growth phase type \"%s\"\n", token);
throw new IOException(String.format("Bad growth phase type \"%s\"\n", token));
}
return result;
}

View File

@ -17,13 +17,12 @@ public class HardinessZoneDeserializer extends StdDeserializer<HardinessZone> {
@Override
public HardinessZone deserialize(JsonParser parser, DeserializationContext context) throws IOException {
HardinessZone result = null;
HardinessZone result;
String token = parser.getText();
try {
result = HardinessZone.valueOf(token.toUpperCase());
} catch (IllegalArgumentException e) {
// TODO: Log
System.err.printf("Unknown Hardiness Zone \"%s\"\n", token);
throw new IOException(String.format("Unknown Hardiness Zone \"%s\"\n", token), e);
}
return result;
}

View File

@ -23,9 +23,7 @@ public class PlantImageDeserializer extends JsonDeserializer<Image> {
try (InputStream is = new FileInputStream(new File(imageUrl.toURI()))) {
result = new Image(is);
} catch (IllegalArgumentException | URISyntaxException e) {
// TODO: Log
e.printStackTrace();
System.err.printf("Cannot find Image \"%s\"\n", imageUrl.getFile());
throw new IOException(String.format("Cannot find Image \"%s\"\n", imageUrl.getFile()));
}
}
return result;

View File

@ -116,16 +116,17 @@ public class PlantListModel {
if (searchString.length() == 0) {
return getPlantList(zone);
} else if (searchString.charAt(0) == '#') {
try {
return getFilteredPlantListById(zone, Long.parseLong(searchString.substring(1)));
} catch (NumberFormatException e) {
if (isPositiveIntegral(searchString.substring(1))) {
Long searchId = Long.parseLong(searchString.substring(1));
return getFilteredPlantListById(zone, searchId);
} else {
return new ArrayList<>();
}
} else {
String caseInsensitiveSearchString = searchString.toLowerCase();
return getFilteredPlantList(zone, plant ->
plant.name().toLowerCase().contains(caseInsensitiveSearchString) ||
plant.description().toLowerCase().contains(caseInsensitiveSearchString)
plant.name().toLowerCase().contains(caseInsensitiveSearchString) ||
plant.description().toLowerCase().contains(caseInsensitiveSearchString)
);
}
}
@ -169,15 +170,24 @@ public class PlantListModel {
}
/**
*
* @param zone selected hardiness zone
* @param from the earliest date to for the filter
* @param to the lastest date for the filter
* @param to the lastest date for the filter
* @return List of Plants with selected saison
* @throws HardinessZoneNotSetException If no {@link HardinessZone} was specified
* @throws IOException If the database cannot be accessed
* @throws IOException If the database cannot be accessed
*/
public List<Plant> getFilteredPlantListBySaisonWithoutGrowthPhase(HardinessZone zone, MonthDay from, MonthDay to) throws HardinessZoneNotSetException, IOException {
return getFilteredPlantList(zone, plant -> plant.lifecycle().stream().anyMatch(growthPhase -> growthPhase.startDate().compareTo(from) >= 0 && (growthPhase.startDate().compareTo(to) <= 0)));
}
/**
* Check if a string can safely be parsed as a positive Integral value (short/int/long)
*
* @param subject The string to be tested
* @return Whether the string contains only digits
*/
private boolean isPositiveIntegral(String subject) {
return subject != null && subject.matches("[0-9]+");
}
}

View File

@ -1,10 +1,7 @@
package ch.zhaw.gartenverwaltung.taskList;
import ch.zhaw.gartenverwaltung.Config;
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
import ch.zhaw.gartenverwaltung.io.JsonTaskDatabase;
import ch.zhaw.gartenverwaltung.io.PlantDatabase;
import ch.zhaw.gartenverwaltung.io.TaskDatabase;
import ch.zhaw.gartenverwaltung.io.*;
import ch.zhaw.gartenverwaltung.types.*;
import java.io.IOException;
@ -26,6 +23,7 @@ public class TaskListModel {
public TaskListModel(){
taskDatabase = new JsonTaskDatabase();
plantDatabase = new JsonPlantDatabase();
}
/**

View File

@ -25,7 +25,6 @@ public class Task {
name= "";
description= "";
startDate = LocalDate.now();
//this.cropId = cropId;
}
public Task(String name, String description, LocalDate startDate, long cropId) {

View File

@ -4,6 +4,7 @@ module ch.zhaw.gartenverwaltung {
requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.datatype.jsr310;
requires com.fasterxml.jackson.datatype.jdk8;
requires java.logging;
opens ch.zhaw.gartenverwaltung to javafx.fxml;
opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind;

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="785.0" prefWidth="899.0"
xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.CropDetailController">
<children>
<ScrollPane fitToWidth="true" prefHeight="759.0" prefWidth="664.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<content>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="503.0" prefWidth="897.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<children>
<Button mnemonicParsing="false" onAction="#goBack" prefHeight="25.0" prefWidth="91.0" text="Go Back">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Button>
<Label fx:id="cropName_label" text="Label">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Label>
<HBox prefHeight="265.0" prefWidth="879.0">
<children>
<GridPane maxWidth="1.7976931348623157E308" prefHeight="296.0" prefWidth="577.0" HBox.hgrow="ALWAYS">
<columnConstraints>
<ColumnConstraints halignment="LEFT" hgrow="SOMETIMES" maxWidth="284.0" minWidth="10.0" prefWidth="97.33334350585938" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="488.99999237060547" minWidth="10.0" prefWidth="481.9999898274739" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="149.66665903727215" minHeight="10.0" prefHeight="149.66665903727215" valignment="TOP" vgrow="SOMETIMES" />
<RowConstraints maxHeight="187.9999647140503" minHeight="10.0" prefHeight="51.00000762939453" vgrow="SOMETIMES" />
<RowConstraints maxHeight="105.66662597656247" minHeight="10.0" prefHeight="54.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="105.66662597656247" minHeight="10.0" prefHeight="46.66666666666666" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label prefHeight="17.0" prefWidth="65.0" text="Description:">
<GridPane.margin>
<Insets top="10.0" />
</GridPane.margin>
</Label>
<Label text="Light-Level:" GridPane.rowIndex="1" />
<Label text="Spacing:" GridPane.rowIndex="2" />
<Label text="Soil-Type:" GridPane.rowIndex="3" />
<Label fx:id="description_label" text="Label" wrapText="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets left="10.0" top="10.0" />
</GridPane.margin>
</Label>
<Label fx:id="light_label" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label fx:id="spacing_label" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label fx:id="soil_label" text="Label" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
</children>
</GridPane>
<ImageView fx:id="imageView" fitHeight="300.0" fitWidth="300.0" pickOnBounds="true" preserveRatio="true" HBox.hgrow="NEVER" />
</children>
</HBox>
<Label text="Growth Phases:">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Label>
<VBox fx:id="growthPhases_vbox" prefHeight="135.0" prefWidth="879.0">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</VBox>
<Button mnemonicParsing="false" onAction="#editTaskList" prefHeight="25.0" prefWidth="92.0" text="Edit Tasklist">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</Button>
<Label text="Pests:" />
<VBox fx:id="pests_vbox" prefHeight="200.0" prefWidth="100.0">
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</VBox>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="NEVER">
<children>
<Label text="Area:">
<HBox.margin>
<Insets right="60.0" />
</HBox.margin>
</Label>
<Label fx:id="area_label" text="Label">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Label>
<Button fx:id="area_button" mnemonicParsing="false" onAction="#setArea" prefHeight="25.0" prefWidth="116.0" text="Add Area" />
</children>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="20.0" layoutY="719.0" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="NEVER">
<children>
<Label text="Location:">
<HBox.margin>
<Insets right="40.0" />
</HBox.margin>
</Label>
<Label fx:id="location_label" text="Label">
<HBox.margin>
<Insets right="10.0" />
</HBox.margin>
</Label>
<Button fx:id="location_button" mnemonicParsing="false" onAction="#setLocation" prefHeight="25.0" prefWidth="115.0" text="Add Location" />
</children>
</HBox>
</children>
</VBox>
</content>
</ScrollPane>
</children>
</AnchorPane>

View File

@ -7,9 +7,7 @@
<?import javafx.scene.layout.VBox?>
<?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.MyPlantsController">
<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">
<children>
@ -21,7 +19,7 @@
<Insets bottom="10.0" />
</VBox.margin>
</Label>
<VBox fx:id="myPlants_vbox" prefHeight="200.0" prefWidth="100.0" VBox.vgrow="ALWAYS" />
<VBox fx:id="myPlants_vbox" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="100.0" VBox.vgrow="ALWAYS" />
<Button fx:id="addPlant_button" mnemonicParsing="false" onAction="#addPlant" prefHeight="45.0" prefWidth="155.0" text="Add new Plant">
<VBox.margin>
<Insets top="10.0" />