diff --git a/src/main/java/ch/zhaw/gartenverwaltung/CropDetailController.java b/src/main/java/ch/zhaw/gartenverwaltung/CropDetailController.java index 7051bfa..7ec8652 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/CropDetailController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/CropDetailController.java @@ -1,5 +1,6 @@ package ch.zhaw.gartenverwaltung; +import ch.zhaw.gartenverwaltung.bootstrap.AppLoader; import ch.zhaw.gartenverwaltung.bootstrap.Inject; import ch.zhaw.gartenverwaltung.io.PlantList; import ch.zhaw.gartenverwaltung.models.Garden; @@ -10,13 +11,18 @@ 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.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.geometry.Pos; -import javafx.scene.control.Button; -import javafx.scene.control.Label; +import javafx.scene.control.*; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; +import javafx.scene.layout.Priority; import javafx.stage.Stage; import java.io.IOException; @@ -34,7 +40,12 @@ public class CropDetailController { @Inject private Garden garden; + @Inject + AppLoader appLoader; + private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName()); + private final ListProperty taskListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); + private final ListProperty pestListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); @FXML private ImageView imageView; @@ -51,9 +62,6 @@ public class CropDetailController { @FXML private Label description_label; - @FXML - private VBox growthPhases_vbox; - @FXML private Label location_label; @@ -63,9 +71,6 @@ public class CropDetailController { @FXML private Button location_button; - @FXML - private VBox pests_vbox; - @FXML private Label soil_label; @@ -73,26 +78,50 @@ public class CropDetailController { private Label spacing_label; @FXML - void editTaskList() { + private Button addTask_button; + @FXML + private ListView taskList_listView; + + @FXML + private ListView pests_listView; + + @FXML + void addTask() throws IOException { + createTaskDialog(true, null); } + /** + * close Window + */ @FXML void goBack() { Stage stage = (Stage) imageView.getScene().getWindow(); stage.close(); } + /** + * open dialog to set area + */ @FXML void setArea() { } + /** + * open dialog to set location + */ @FXML void setLocation() { } + /** + * set labels and image from selected {@link Crop} + * set icons for buttons + * @param crop {@link Crop} which will be displayed + * @throws PlantNotFoundException exception + */ public void setPlantFromCrop(Crop crop) throws PlantNotFoundException { this.crop = crop; try { @@ -109,22 +138,65 @@ public class CropDetailController { } area_label.setText(""); location_label.setText(""); - createTaskLists(crop); - createPestList(plant); + + setTaskListProperty(crop); + taskList_listView.itemsProperty().bind(taskListProperty); + + pestListProperty.addAll(plant.pests()); + pests_listView.itemsProperty().bind(pestListProperty); + + } catch (HardinessZoneNotSetException | IOException e) { throw new PlantNotFoundException(); } + setIconToButton(addTask_button, "addIcon.png"); + setIconToButton(area_button, "areaIcon.png"); + setIconToButton(location_button, "locationIcon.png"); + setCellFactoryPests(); + setCellFactoryTasks(); } - private void createTaskLists(Crop crop) { + private void setCellFactoryTasks() { + taskList_listView.setCellFactory(param -> new ListCell<>() { + @Override + protected void updateItem(Task task, boolean empty) { + super.updateItem(task, empty); + + if (empty || task == null) { + setText(null); + setGraphic(null); + } else { + setText(""); + setGraphic(createTaskHBox(task)); + } + } + }); + } + + private void setCellFactoryPests() { + pests_listView.setCellFactory(param -> new ListCell<>() { + @Override + protected void updateItem(Pest pest, boolean empty) { + super.updateItem(pest, empty); + + if (empty || pest == null) { + setText(null); + setGraphic(null); + } else { + setText(""); + setGraphic(createPestHBox(pest)); + } + } + }); + } + + private void setTaskListProperty(Crop crop) { crop.getCropId().ifPresent(id -> { List taskList; try { taskList = gardenSchedule.getTaskListForCrop(id); - for (Task task : taskList) { - Label label = new Label(task.getDescription()); - growthPhases_vbox.getChildren().add(label); - } + taskListProperty.clear(); + taskListProperty.addAll(taskList); } catch (IOException e) { // TODO: Alert LOG.log(Level.SEVERE, "Could not get task list for crop", e.getCause()); @@ -132,21 +204,100 @@ public class CropDetailController { }); } - private void createPestList(Plant plant) { - List 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); + private HBox createTaskHBox(Task task) { + HBox hBox = new HBox(); + Label taskName = new Label(task.getName()+": "); + taskName.setStyle("-fx-font-weight: bold"); + Label taskDescription = new Label(task.getDescription()); + taskDescription.setWrapText(true); + taskDescription.setMaxWidth(2000); + HBox.setHgrow(taskDescription, Priority.ALWAYS); + + Button edit = new Button(); + Button delete = new Button(); + setIconToButton(edit, "editIcon.png"); + setIconToButton(delete, "deleteIcon.png"); + edit.setOnAction(getEditTaskEvent(task)); + + hBox.getChildren().addAll(taskName, taskDescription, edit, delete); + return hBox; + } + + private HBox createPestHBox(Pest pest) { + 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); + Button button = new Button("Get Counter Measures"); + hBox.getChildren().addAll(label, label1, button); + return hBox; + } + + /** + * adds icon to button + * @param button the button which get the icon + * @param iconFileName file name of icon + */ + private void setIconToButton(Button button, String iconFileName) { + Image img = new Image(String.valueOf(getClass().getResource("icons/" + iconFileName))); + ImageView imageView = new ImageView(img); + imageView.setFitHeight(20); + imageView.setPreserveRatio(true); + button.setGraphic(imageView); + } + + private EventHandler getEditTaskEvent(Task task) { + return (event) -> { + try { + createTaskDialog(false, task); + } catch (IOException e) { + e.printStackTrace(); + } + }; + } + + private void createTaskDialog(boolean newTask, Task givenTask) throws IOException { + Dialog dialog = new Dialog<>(); + dialog.setTitle("Set Task"); + dialog.setHeaderText("Add/Edit Task:"); + dialog.setResizable(false); + + DialogPane dialogPane = dialog.getDialogPane(); + + ButtonType saveTask; + if(newTask) { + saveTask = new ButtonType("Add", ButtonBar.ButtonData.OK_DONE); + } else { + saveTask = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE); } + dialogPane.getButtonTypes().addAll(saveTask, ButtonType.CANCEL); + + if (appLoader.loadPaneToDialog("TaskFormular.fxml", dialogPane) instanceof TaskFormularController controller) { + controller.setCorp(this.crop); + if (!newTask) { + controller.setTaskValue(givenTask); + } + dialog.setResultConverter(button -> button.equals(saveTask) ? controller.returnResult() : null); + + dialog.showAndWait() + .ifPresent(task -> { + if (newTask) { + try { + gardenSchedule.addTask(task); + setTaskListProperty(this.crop); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + //ToDo method to edit task + setTaskListProperty(this.crop); + } + }); + } + } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/HomeController.java b/src/main/java/ch/zhaw/gartenverwaltung/HomeController.java index 7df4661..5c9014c 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/HomeController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/HomeController.java @@ -1,5 +1,47 @@ package ch.zhaw.gartenverwaltung; -public class HomeController -{ +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +import java.net.URL; +import java.util.ResourceBundle; + +public class HomeController implements Initializable { + + @FXML + private ImageView imageViewDavid; + + @FXML + private ImageView imageViewElias; + + @FXML + private ImageView imageViewGian; + + @FXML + private ImageView imageViewPhilippe; + + @FXML + private ImageView imageViewRoman; + + @Override + public void initialize(URL location, ResourceBundle resources) { + setImages(imageViewDavid, ""); + setImages(imageViewElias, ""); + setImages(imageViewGian, ""); + setImages(imageViewRoman, ""); + setImages(imageViewPhilippe, ""); + } + + private void setImages(ImageView imageView, String photoName) { + Image img; + if (photoName.equals("")) { + img = new Image(String.valueOf(getClass().getResource("icons/userIcon.png"))); + } else { + img = new Image(String.valueOf(getClass().getResource("icons/" + photoName))); + } + imageView.setImage(img); + } } + diff --git a/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java b/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java index fca8b69..2cc05d3 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/MainFXMLController.java @@ -6,7 +6,9 @@ import ch.zhaw.gartenverwaltung.bootstrap.ChangeViewEvent; import ch.zhaw.gartenverwaltung.bootstrap.Inject; import javafx.event.EventHandler; import javafx.fxml.FXML; -import javafx.scene.control.Button; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; @@ -33,30 +35,71 @@ public class MainFXMLController { private Button mySchedule_button; @FXML - private Button plants_button; + private Button settings_button; + @FXML + private Button tutorial_button; + + /** + * go to home pane + */ @FXML void goToHome() { showPaneAsMainView("Home.fxml"); styleChangeButton(home_button); } + /** + * go to my garden pane + */ @FXML void goToMyPlants() { showPaneAsMainView("MyGarden.fxml"); styleChangeButton(myGarden_button); } + /** + * go to the schedule pane + */ @FXML void goToMySchedule() { showPaneAsMainView("MySchedule.fxml"); styleChangeButton(mySchedule_button); } + /** + * open dialog of the settings + * @throws IOException exception + */ @FXML - void goToPlants() { - showPaneAsMainView("Plants.fxml"); - styleChangeButton(plants_button); + public void openSettings() throws IOException { + Dialog dialog = new Dialog<>(); + dialog.setTitle("Settings"); + dialog.setHeaderText("Settings"); + dialog.setResizable(false); + + DialogPane dialogPane = dialog.getDialogPane(); + + ButtonType saveSettings = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE); + dialogPane.getButtonTypes().addAll(saveSettings, ButtonType.CANCEL); + + if (appLoader.loadPaneToDialog("Settings.fxml", dialogPane) instanceof SettingsController controller) { + + dialog.showAndWait() + .ifPresent(button -> { + if (button.equals(saveSettings)) { + controller.saveSettings(); + } + }); + } + } + + /** + * go to Tutorial pane + */ + public void goToTutorial() { + showPaneAsMainView("Tutorial.fxml"); + styleChangeButton(tutorial_button); } /** @@ -81,10 +124,15 @@ public class MainFXMLController { private final EventHandler changeMainViewHandler = (ChangeViewEvent event) -> showPaneAsMainView(event.view()); + /** + * preload all menu bar panes + * @throws IOException exception + */ private void preloadPanes() throws IOException { appLoader.loadAndCacheFxml("MyGarden.fxml"); appLoader.loadAndCacheFxml("MySchedule.fxml"); appLoader.loadAndCacheFxml("Plants.fxml"); + appLoader.loadAndCacheFxml("Tutorial.fxml"); } private void styleChangeButton(Button button) { @@ -100,11 +148,32 @@ public class MainFXMLController { public void init() { try { preloadPanes(); - showPaneAsMainView("Home.fxml"); - styleChangeButton(home_button); + showPaneAsMainView("MyGarden.fxml"); + styleChangeButton(myGarden_button); } catch (IOException e) { LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e); } + setIconToButton(home_button, "homeIcon.png"); + setIconToButton(settings_button, "settingsIcon.png"); + Settings.getInstance().getShowTutorialProperty().addListener((observable, oldValue, newValue) -> { + tutorial_button.setVisible(newValue); + }); + tutorial_button.setVisible(Settings.getInstance().getShowTutorial()); } + + /** + * adds icon to given button + * @param button the button which get the icon + * @param iconFileName file name of icon + */ + private void setIconToButton(Button button, String iconFileName) { + Image img = new Image(String.valueOf(getClass().getResource("icons/" + iconFileName))); + ImageView imageView = new ImageView(img); + imageView.setFitHeight(20); + imageView.setPreserveRatio(true); + button.setGraphic(imageView); + } + + } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/MyGardenController.java b/src/main/java/ch/zhaw/gartenverwaltung/MyGardenController.java index e54e608..b6270ca 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/MyGardenController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/MyGardenController.java @@ -13,15 +13,12 @@ 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.control.*; +import javafx.scene.image.Image; 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; @@ -42,39 +39,64 @@ public class MyGardenController { @FXML public AnchorPane myGardenRoot; @FXML - private VBox myPlants_vbox; + private Button addPlant_button; + @FXML + private ListView myGarden_listView; + /** + * initialize crop list + * add listener for crop list + * set icon for button + */ @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); - } + System.out.println("once"); + setIconToButton(addPlant_button, "addIcon.png"); + myGarden_listView.itemsProperty().bind(garden.getPlantedCrops()); + setCellFactory(); } + /** + * redirect to plant fxml file + */ @FXML void addPlant() { myGardenRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "Plants.fxml")); } - private void createPlantView(List crops) throws HardinessZoneNotSetException, IOException { - myPlants_vbox.getChildren().clear(); - for (Crop crop : crops) { - HBox hBox = createPlantView(crop); - myPlants_vbox.getChildren().add(hBox); - } + /** + * set cell factory to load {@link HBox} as list view content + */ + private void setCellFactory() { + myGarden_listView.setCellFactory(param -> new ListCell<>() { + @Override + protected void updateItem(Crop crop, boolean empty) { + super.updateItem(crop, empty); + + if (empty || crop == null) { + setText(null); + setGraphic(null); + } else { + try { + setText(""); + setGraphic(createHBoxForListView(crop)); + } catch (HardinessZoneNotSetException | IOException e) { + LOG.log(Level.WARNING, "Could not get plant for Cell", e); + } + } + } + }); } - private HBox createPlantView(Crop crop) throws HardinessZoneNotSetException, IOException { + /** + * Creates and returns HBox of the crop + * @param crop {@link Crop} which is selected + * @return {@link HBox} of the {@link Crop} + * @throws HardinessZoneNotSetException exception + * @throws IOException exception + */ + private HBox createHBoxForListView(Crop crop) throws HardinessZoneNotSetException, IOException { //ToDo add better design Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(); HBox hBox = new HBox(10); @@ -91,8 +113,10 @@ public class MyGardenController { label.setMaxWidth(2000); HBox.setHgrow(label, Priority.ALWAYS); - Button details = new Button("Details"); - Button delete = new Button("delete"); + Button details = new Button(); + Button delete = new Button(); + setIconToButton(details, "detailsIcon.png"); + setIconToButton(delete, "deleteIcon.png"); details.setOnAction(getGoToCropDetailEvent(crop)); delete.setOnAction(getDeleteCropEvent(crop)); @@ -100,6 +124,24 @@ public class MyGardenController { return hBox; } + /** + * adds icon to button + * @param button the button which get the icon + * @param iconFileName file name of icon + */ + private void setIconToButton(Button button, String iconFileName) { + Image img = new Image(String.valueOf(getClass().getResource("icons/" + iconFileName))); + ImageView imageView = new ImageView(img); + imageView.setFitHeight(20); + imageView.setPreserveRatio(true); + button.setGraphic(imageView); + } + + /** + * open detail window of the selected {@link Crop} + * @param crop {@link Crop} which is selected + * @return {@link EventHandler} for button + */ private EventHandler getGoToCropDetailEvent(Crop crop) { return (event) -> { try { @@ -117,6 +159,11 @@ public class MyGardenController { }; } + /** + * open alert for deleting the selected {@link Crop} + * @param crop {@link Crop} which is selected + * @return {@link EventHandler} for button + */ private EventHandler getDeleteCropEvent(Crop crop) { return (event) -> { try { @@ -127,9 +174,16 @@ public class MyGardenController { }; } + /** + * Alert to confirm that the crop can be deleted. + * @param crop {@link Crop} which is selected + * @throws IOException exception + * @throws HardinessZoneNotSetException exception + */ private void showConfirmation(Crop crop) throws IOException, HardinessZoneNotSetException { + Plant plant = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get(); Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setTitle("Delete Crop"); + alert.setTitle("Delete " + plant.name()); alert.setHeaderText("Are you sure want to delete this Crop?"); alert.setContentText("Deleting this crop will remove all associated tasks from your schedule."); diff --git a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java index 8b821c1..5961c5f 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/PlantsController.java @@ -41,7 +41,6 @@ public class PlantsController { private Plant selectedPlant = null; private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A; - // TODO: move to model private final ListProperty plantListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); @FXML @@ -269,7 +268,7 @@ public class PlantsController { list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { if (newValue != null) { selectedPlant = newValue; - description_plant.setText(selectedPlant.description()); + description_plant.setText(getPlantDescription()); selectSowDay_button.setDisable(false); Image img1; if (selectedPlant.image() != null) { @@ -288,6 +287,20 @@ public class PlantsController { }); } + /** + * creates {@link String} of the plant information. + * @return return {@link Plant} description + */ + private String getPlantDescription() { + StringBuilder sb = new StringBuilder(); + sb.append("Name: ").append(selectedPlant.name()) + .append("\nDescription:\n").append(selectedPlant.description()) + .append("\nLight Level: ").append(selectedPlant.light()) + .append("\nSoil: ").append(selectedPlant.soil()) + .append("\nSpacing: ").append(selectedPlant.spacing()); + return sb.toString(); + } + /** * clears the ListView of entries diff --git a/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java b/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java index e3722fc..c6ff944 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/SelectSowDayController.java @@ -21,6 +21,11 @@ public class SelectSowDayController { @FXML public ToggleGroup phase_group; + /** + * if sow date radio button was selected return sow date + * if sow date was not selected get sow from harvest day and return sow date + * @return {@link LocalDate} of the sow date + */ public LocalDate retrieveResult() { LocalDate sowDate = datepicker.getValue(); if (harvest_radio.isSelected()) { @@ -53,6 +58,10 @@ public class SelectSowDayController { harvest_radio.setUserData(GrowthPhaseType.HARVEST); } + /** + * Disable save button when date picker is empty + * @param saveButton {@link Button} to be disabled + */ public void initSaveButton(Button saveButton) { saveButton.disableProperty().bind(datepicker.valueProperty().isNull()); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java index 792f5c0..c15454c 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java @@ -1,10 +1,13 @@ package ch.zhaw.gartenverwaltung; import ch.zhaw.gartenverwaltung.types.HardinessZone; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; public class Settings { private HardinessZone currentHardinessZone = HardinessZone.ZONE_8A; private static Settings instance; + private final BooleanProperty showTutorial = new SimpleBooleanProperty(false); static { instance = new Settings(); @@ -23,4 +26,16 @@ public class Settings { public void setCurrentHardinessZone(HardinessZone currentHardinessZone) { this.currentHardinessZone = currentHardinessZone; } + + public void setShowTutorial (boolean showTutorial) { + this.showTutorial.setValue(showTutorial); + } + + public BooleanProperty getShowTutorialProperty() { + return this.showTutorial; + } + + public boolean getShowTutorial() { + return this.showTutorial.get(); + } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/SettingsController.java b/src/main/java/ch/zhaw/gartenverwaltung/SettingsController.java new file mode 100644 index 0000000..9a8158f --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/SettingsController.java @@ -0,0 +1,40 @@ +package ch.zhaw.gartenverwaltung; + +import ch.zhaw.gartenverwaltung.types.HardinessZone; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; + +import java.net.URL; +import java.util.ResourceBundle; + +public class SettingsController implements Initializable { + Settings settings = Settings.getInstance(); + + @FXML + private ComboBox selectHardinessZone_comboBox; + + @FXML + private CheckBox showTutorial_checkBox; + + /** + * save selected values to {@link Settings} + */ + public void saveSettings() { + settings.setShowTutorial(showTutorial_checkBox.isSelected()); + settings.setCurrentHardinessZone(selectHardinessZone_comboBox.getValue()); + } + + /** + * save default values form {@link Settings} + * @param location location + * @param resources resources + */ + @Override + public void initialize(URL location, ResourceBundle resources) { + showTutorial_checkBox.setSelected(settings.getShowTutorial()); + selectHardinessZone_comboBox.getItems().addAll(HardinessZone.values()); + selectHardinessZone_comboBox.setValue(settings.getCurrentHardinessZone()); + } +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/TaskFormularController.java b/src/main/java/ch/zhaw/gartenverwaltung/TaskFormularController.java new file mode 100644 index 0000000..938eea9 --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/TaskFormularController.java @@ -0,0 +1,86 @@ +package ch.zhaw.gartenverwaltung; + +import ch.zhaw.gartenverwaltung.types.Crop; +import ch.zhaw.gartenverwaltung.types.Task; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.DateCell; +import javafx.scene.control.DatePicker; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.util.Callback; + +import java.net.URL; +import java.time.LocalDate; +import java.util.ResourceBundle; + +public class TaskFormularController implements Initializable { + private Crop crop; + + @FXML + private TextArea description_area; + + @FXML + private DatePicker end_datePicker; + + @FXML + private TextField interval_field; + + @FXML + private DatePicker start_datePicker; + + @FXML + private TextField taskName_field; + + + public Task returnResult() { + Task task = new Task(taskName_field.getText(), description_area.getText(), + start_datePicker.getValue(), end_datePicker.getValue(), + Integer.parseInt(interval_field.getText()), crop.getCropId().get()); + return task; + } + + public void setCorp(Crop crop) { + this.crop = crop; + } + + public void setTaskValue(Task task) { + taskName_field.setText(task.getName()); + description_area.setText(task.getDescription()); + start_datePicker.setValue(task.getStartDate()); + end_datePicker.setValue(task.getEndDate().orElse(null)); + if(task.getInterval().orElse(null)!=null) { + interval_field.setText(task.getInterval().get().toString()); + } else { + interval_field.setText(null); + } + } + + private Callback getDayCellFactory() { + + return (datePicker) -> new DateCell() { + private final LocalDate today = LocalDate.now(); + + @Override + public void updateItem(LocalDate item, boolean empty) { + super.updateItem(item, empty); + setDisable(true); + setStyle("-fx-background-color: #ffc0cb;"); + + if (item.compareTo(today) > 0 && item.compareTo(crop.getStartDate()) > 0) { + setDisable(false); + setStyle("-fx-background-color: #32CD32;"); + } + } + }; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + start_datePicker.setDayCellFactory(getDayCellFactory()); + start_datePicker.setEditable(false); + + end_datePicker.setDayCellFactory(getDayCellFactory()); + end_datePicker.setEditable(false); + } +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/TutorialController.java b/src/main/java/ch/zhaw/gartenverwaltung/TutorialController.java new file mode 100644 index 0000000..aa02930 --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/TutorialController.java @@ -0,0 +1,6 @@ +package ch.zhaw.gartenverwaltung; + + +public class TutorialController { + +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonCropList.java b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonCropList.java index f9ddc3e..c7fd0ea 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonCropList.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonCropList.java @@ -53,6 +53,7 @@ public class JsonCropList implements CropList { public JsonCropList(URL dataSource) { this.dataSource = dataSource; } + /** * {@inheritDoc} */ diff --git a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantList.java b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantList.java index 6132477..7b76f70 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantList.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonPlantList.java @@ -25,7 +25,7 @@ import java.util.Optional; * The reads are cached to minimize file-io operations. */ public class JsonPlantList implements PlantList { - private final URL dataSource = getClass().getResource("plantdb.json"); + private final URL dataSource; private HardinessZone currentZone; private Map plantMap = Collections.emptyMap(); @@ -44,6 +44,13 @@ public class JsonPlantList implements PlantList { imageModule.addDeserializer(Image.class, new PlantImageDeserializer()); } + public JsonPlantList() { + this.dataSource = getClass().getResource("plantdb.json"); + } + public JsonPlantList(URL dataSource) { + this.dataSource = dataSource; + } + /** * If no data is currently loaded, or the specified zone differs * from the {@link #currentZone}, data is loaded from {@link #dataSource}. diff --git a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonTaskList.java b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonTaskList.java index bda9aa8..6b18f72 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/io/JsonTaskList.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/io/JsonTaskList.java @@ -25,7 +25,7 @@ import java.util.Map; */ public class JsonTaskList implements TaskList { IdProvider idProvider; - private final URL dataSource = getClass().getResource("taskdb.json"); + private final URL dataSource; private final static String INVALID_DATASOURCE_MSG = "Invalid datasource specified!"; private Map taskMap = Collections.emptyMap(); @@ -43,6 +43,13 @@ public class JsonTaskList implements TaskList { timeModule.addSerializer(LocalDate.class, dateSerializer); } + public JsonTaskList() { + this.dataSource = getClass().getResource("taskdb.json"); + } + public JsonTaskList(URL dataSource) { + this.dataSource = dataSource; + } + /** * If no data is currently loaded, data is loaded from {@link #dataSource}. * In any case, the values of {@link #taskMap} are returned. @@ -96,9 +103,9 @@ public class JsonTaskList implements TaskList { if(taskMap.isEmpty()) { loadTaskListFromFile(); } - if(task.getId() == 0) { - task.withId(idProvider.incrementAndGet()); - } + long id = task.getId().orElse(idProvider.incrementAndGet()); + + taskMap.put(id, task.withId(id)); writeTaskListToFile(); } @@ -114,8 +121,9 @@ public class JsonTaskList implements TaskList { if(taskMap.isEmpty()) { loadTaskListFromFile(); } - if(taskMap.containsKey(task.getId())){ - taskMap.remove(task.getId()); + Long taskId = task.getId().orElseThrow(IOException::new); + if(taskMap.containsKey(taskId)){ + taskMap.remove(taskId); writeTaskListToFile(); } } @@ -155,7 +163,7 @@ public class JsonTaskList implements TaskList { taskMap = result.stream() .collect(HashMap::new, - (res, task) -> res.put(task.getId(), task), + (res, task) -> res.put(task.getId().orElse(0L), task), (existing, replacement) -> {}); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java index 16de6c3..df15fc4 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java @@ -9,7 +9,7 @@ import java.util.Optional; * May be created using the builder pattern. */ public class Task { - private long id; + private Long id; private final String name; private final String description; private final LocalDate startDate; @@ -62,7 +62,7 @@ public class Task { } // Getters - public long getId() { return id; } + public Optional getId() { return Optional.ofNullable(id); } public String getName() { return name; } public String getDescription() { return description; } public LocalDate getStartDate() { return startDate; } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java b/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java index 8ae7862..2e471cb 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/TaskTemplate.java @@ -34,6 +34,7 @@ public class TaskTemplate { public void setRelativeEndDate(Integer relativeEndDate) { this.relativeEndDate = relativeEndDate; } + public void setInterval(Integer interval) { this.interval = interval; } @@ -45,13 +46,10 @@ public class TaskTemplate { } public Task generateTask(LocalDate realStartDate, long cropId) { - Task task = new Task(name, description, realStartDate.plusDays(relativeStartDate), cropId); - if (relativeEndDate != null) { - task.withEndDate(realStartDate.plusDays(relativeEndDate)); - } - if (interval != null) { - task.withInterval(interval); - } - return task; + LocalDate endDate = relativeEndDate != null ? realStartDate.plusDays(relativeEndDate) : null; + + return new Task(name, description, realStartDate.plusDays(relativeStartDate), cropId) + .withInterval(interval) + .withEndDate(endDate); } } diff --git a/src/main/resources/ch/zhaw/gartenverwaltung/CropDetail.fxml b/src/main/resources/ch/zhaw/gartenverwaltung/CropDetail.fxml index ed3a476..c0f0a7c 100644 --- a/src/main/resources/ch/zhaw/gartenverwaltung/CropDetail.fxml +++ b/src/main/resources/ch/zhaw/gartenverwaltung/CropDetail.fxml @@ -3,6 +3,7 @@ + @@ -12,13 +13,11 @@ - - + - + @@ -80,27 +79,27 @@ -