Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f049f86ab | ||
|
|
bcb36b89c7 | ||
|
|
f7105f041c | ||
|
|
b0369e3174 | ||
|
|
8c20dcaadb | ||
|
|
95b0f7e13d | ||
|
|
2312149256 | ||
|
|
ffc7f5174e | ||
|
|
8d3fbc06ad | ||
|
|
dcb97f1c55 |
@@ -1,5 +1,6 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
import ch.zhaw.gartenverwaltung.bootstrap.AppLoader;
|
||||||
import ch.zhaw.gartenverwaltung.bootstrap.Inject;
|
import ch.zhaw.gartenverwaltung.bootstrap.Inject;
|
||||||
import ch.zhaw.gartenverwaltung.io.PlantList;
|
import ch.zhaw.gartenverwaltung.io.PlantList;
|
||||||
import ch.zhaw.gartenverwaltung.models.Garden;
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
||||||
@@ -10,14 +11,18 @@ 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.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.fxml.FXML;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -35,7 +40,12 @@ public class CropDetailController {
|
|||||||
@Inject
|
@Inject
|
||||||
private Garden garden;
|
private Garden garden;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AppLoader appLoader;
|
||||||
|
|
||||||
private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName());
|
private static final Logger LOG = Logger.getLogger(CropDetailController.class.getName());
|
||||||
|
private final ListProperty<Task> taskListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
|
private final ListProperty<Pest> pestListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ImageView imageView;
|
private ImageView imageView;
|
||||||
@@ -52,9 +62,6 @@ public class CropDetailController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label description_label;
|
private Label description_label;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private VBox growthPhases_vbox;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label location_label;
|
private Label location_label;
|
||||||
|
|
||||||
@@ -64,9 +71,6 @@ public class CropDetailController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button location_button;
|
private Button location_button;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private VBox pests_vbox;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label soil_label;
|
private Label soil_label;
|
||||||
|
|
||||||
@@ -74,11 +78,17 @@ public class CropDetailController {
|
|||||||
private Label spacing_label;
|
private Label spacing_label;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button editTaskList_button;
|
private Button addTask_button;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void editTaskList() {
|
private ListView<Task> taskList_listView;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ListView<Pest> pests_listView;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void addTask() throws IOException {
|
||||||
|
createTaskDialog(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,25 +138,65 @@ public class CropDetailController {
|
|||||||
}
|
}
|
||||||
area_label.setText("");
|
area_label.setText("");
|
||||||
location_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) {
|
} catch (HardinessZoneNotSetException | IOException e) {
|
||||||
throw new PlantNotFoundException();
|
throw new PlantNotFoundException();
|
||||||
}
|
}
|
||||||
setIconToButton(editTaskList_button, "editIcon.png");
|
setIconToButton(addTask_button, "addIcon.png");
|
||||||
setIconToButton(area_button, "areaIcon.png");
|
setIconToButton(area_button, "areaIcon.png");
|
||||||
setIconToButton(location_button, "locationIcon.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 -> {
|
crop.getCropId().ifPresent(id -> {
|
||||||
List<Task> taskList;
|
List<Task> taskList;
|
||||||
try {
|
try {
|
||||||
taskList = gardenSchedule.getTaskListForCrop(id);
|
taskList = gardenSchedule.getTaskListForCrop(id);
|
||||||
for (Task task : taskList) {
|
taskListProperty.clear();
|
||||||
Label label = new Label(task.getDescription());
|
taskListProperty.addAll(taskList);
|
||||||
growthPhases_vbox.getChildren().add(label);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO: Alert
|
// TODO: Alert
|
||||||
LOG.log(Level.SEVERE, "Could not get task list for crop", e.getCause());
|
LOG.log(Level.SEVERE, "Could not get task list for crop", e.getCause());
|
||||||
@@ -154,22 +204,37 @@ public class CropDetailController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPestList(Plant plant) {
|
private HBox createTaskHBox(Task task) {
|
||||||
List<Pest> pests = plant.pests();
|
HBox hBox = new HBox();
|
||||||
for (Pest pest : pests) {
|
Label taskName = new Label(task.getName()+": ");
|
||||||
Label label = new Label(pest.name() + ":");
|
taskName.setStyle("-fx-font-weight: bold");
|
||||||
label.setStyle("-fx-font-weight: bold");
|
Label taskDescription = new Label(task.getDescription());
|
||||||
HBox hBox = new HBox();
|
taskDescription.setWrapText(true);
|
||||||
hBox.fillHeightProperty();
|
taskDescription.setMaxWidth(2000);
|
||||||
Label label1 = new Label(pest.description());
|
HBox.setHgrow(taskDescription, Priority.ALWAYS);
|
||||||
label1.setAlignment(Pos.TOP_LEFT);
|
|
||||||
label1.setWrapText(true);
|
Button edit = new Button();
|
||||||
label1.setMaxWidth(600);
|
Button delete = new Button();
|
||||||
label1.setMaxHeight(100);
|
setIconToButton(edit, "editIcon.png");
|
||||||
Button button = new Button("Get Counter Measures");
|
setIconToButton(delete, "deleteIcon.png");
|
||||||
hBox.getChildren().addAll(label1, button);
|
edit.setOnAction(getEditTaskEvent(task));
|
||||||
pests_vbox.getChildren().addAll(label, hBox);
|
|
||||||
}
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,4 +249,55 @@ public class CropDetailController {
|
|||||||
imageView.setPreserveRatio(true);
|
imageView.setPreserveRatio(true);
|
||||||
button.setGraphic(imageView);
|
button.setGraphic(imageView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EventHandler<ActionEvent> getEditTaskEvent(Task task) {
|
||||||
|
return (event) -> {
|
||||||
|
try {
|
||||||
|
createTaskDialog(false, task);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTaskDialog(boolean newTask, Task givenTask) throws IOException {
|
||||||
|
Dialog<Task> 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@@ -40,6 +43,9 @@ public class MainFXMLController {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button tutorial_button;
|
private Button tutorial_button;
|
||||||
|
|
||||||
|
private final Stage tutorialModal = new Stage();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go to home pane
|
* go to home pane
|
||||||
*/
|
*/
|
||||||
@@ -95,11 +101,23 @@ public class MainFXMLController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go to Tutorial pane
|
* Show the tutorial window
|
||||||
*/
|
*/
|
||||||
public void goToTutorial() {
|
public void showTutorial() {
|
||||||
showPaneAsMainView("Tutorial.fxml");
|
if (!tutorialModal.isShowing()) {
|
||||||
styleChangeButton(tutorial_button);
|
if (tutorialModal.getScene() == null) {
|
||||||
|
try {
|
||||||
|
appLoader.loadSceneToStage("Tutorial.fxml", tutorialModal);
|
||||||
|
tutorialModal.initModality(Modality.NONE);
|
||||||
|
tutorialModal.setResizable(false);
|
||||||
|
tutorialModal.sizeToScene();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.SEVERE, "Could not load Tutorial");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tutorialModal.show();
|
||||||
|
}
|
||||||
|
tutorialModal.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,7 +150,6 @@ public class MainFXMLController {
|
|||||||
appLoader.loadAndCacheFxml("MyGarden.fxml");
|
appLoader.loadAndCacheFxml("MyGarden.fxml");
|
||||||
appLoader.loadAndCacheFxml("MySchedule.fxml");
|
appLoader.loadAndCacheFxml("MySchedule.fxml");
|
||||||
appLoader.loadAndCacheFxml("Plants.fxml");
|
appLoader.loadAndCacheFxml("Plants.fxml");
|
||||||
appLoader.loadAndCacheFxml("Tutorial.fxml");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void styleChangeButton(Button button) {
|
private void styleChangeButton(Button button) {
|
||||||
@@ -153,12 +170,14 @@ public class MainFXMLController {
|
|||||||
} 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);
|
||||||
}
|
}
|
||||||
|
mainPane.getScene().getWindow().setOnCloseRequest(this::closeWindowHandler);
|
||||||
setIconToButton(home_button, "homeIcon.png");
|
setIconToButton(home_button, "homeIcon.png");
|
||||||
setIconToButton(settings_button, "settingsIcon.png");
|
setIconToButton(settings_button, "settingsIcon.png");
|
||||||
Settings.getInstance().getShowTutorialProperty().addListener((observable, oldValue, newValue) -> {
|
tutorial_button.visibleProperty().bind(Settings.getInstance().getShowTutorialProperty());
|
||||||
tutorial_button.setVisible(newValue);
|
}
|
||||||
});
|
|
||||||
tutorial_button.setVisible(Settings.getInstance().getShowTutorial());
|
private void closeWindowHandler(WindowEvent windowEvent) {
|
||||||
|
tutorialModal.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,7 +192,4 @@ public class MainFXMLController {
|
|||||||
imageView.setPreserveRatio(true);
|
imageView.setPreserveRatio(true);
|
||||||
button.setGraphic(imageView);
|
button.setGraphic(imageView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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<DatePicker, DateCell> getDayCellFactory() {
|
||||||
|
|
||||||
|
return (datePicker) -> new DateCell() {
|
||||||
|
private final LocalDate today = LocalDate.now();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateItem(LocalDate item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
setDisable(true);
|
||||||
|
setStyle("-fx-background-color: #ffc0cb;");
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,61 @@
|
|||||||
package ch.zhaw.gartenverwaltung;
|
package ch.zhaw.gartenverwaltung;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class TutorialController {
|
public class TutorialController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public Button previousPageButton;
|
||||||
|
@FXML
|
||||||
|
public Button nextPageButton;
|
||||||
|
@FXML
|
||||||
|
public StackPane tourPages;
|
||||||
|
public ImageView imgAddNewPlant;
|
||||||
|
public ImageView imgTaskList;
|
||||||
|
public ImageView imgSelectDate;
|
||||||
|
|
||||||
|
private int page = 0;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
|
||||||
|
Image placeholder = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
||||||
|
imgAddNewPlant.setImage(placeholder);
|
||||||
|
imgSelectDate.setImage(placeholder);
|
||||||
|
imgTaskList.setImage(placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void viewNextPage() {
|
||||||
|
page++;
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
}
|
||||||
|
public void viewPreviousPage() {
|
||||||
|
page--;
|
||||||
|
switchViews();
|
||||||
|
setButtonAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setButtonAbilities() {
|
||||||
|
previousPageButton.setDisable(page <= 0);
|
||||||
|
nextPageButton.setDisable(page >= tourPages.getChildren().size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchViews() {
|
||||||
|
tourPages.getChildren().forEach(node -> node.setOpacity(0));
|
||||||
|
tourPages.getChildren().get(page).setOpacity(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeTutorial() {
|
||||||
|
Stage root = (Stage) tourPages.getScene().getWindow();
|
||||||
|
root.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,9 +103,9 @@ public class JsonTaskList implements TaskList {
|
|||||||
if(taskMap.isEmpty()) {
|
if(taskMap.isEmpty()) {
|
||||||
loadTaskListFromFile();
|
loadTaskListFromFile();
|
||||||
}
|
}
|
||||||
if(task.getId() == 0) {
|
long id = task.getId().orElse(idProvider.incrementAndGet());
|
||||||
task.withId(idProvider.incrementAndGet());
|
|
||||||
}
|
taskMap.put(id, task.withId(id));
|
||||||
writeTaskListToFile();
|
writeTaskListToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,8 +121,9 @@ public class JsonTaskList implements TaskList {
|
|||||||
if(taskMap.isEmpty()) {
|
if(taskMap.isEmpty()) {
|
||||||
loadTaskListFromFile();
|
loadTaskListFromFile();
|
||||||
}
|
}
|
||||||
if(taskMap.containsKey(task.getId())){
|
Long taskId = task.getId().orElseThrow(IOException::new);
|
||||||
taskMap.remove(task.getId());
|
if(taskMap.containsKey(taskId)){
|
||||||
|
taskMap.remove(taskId);
|
||||||
writeTaskListToFile();
|
writeTaskListToFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +163,7 @@ public class JsonTaskList implements TaskList {
|
|||||||
|
|
||||||
taskMap = result.stream()
|
taskMap = result.stream()
|
||||||
.collect(HashMap::new,
|
.collect(HashMap::new,
|
||||||
(res, task) -> res.put(task.getId(), task),
|
(res, task) -> res.put(task.getId().orElse(0L), task),
|
||||||
(existing, replacement) -> {});
|
(existing, replacement) -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.util.Optional;
|
|||||||
* May be created using the builder pattern.
|
* May be created using the builder pattern.
|
||||||
*/
|
*/
|
||||||
public class Task {
|
public class Task {
|
||||||
private long id;
|
private Long id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String description;
|
private final String description;
|
||||||
private final LocalDate startDate;
|
private final LocalDate startDate;
|
||||||
@@ -62,7 +62,7 @@ public class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
public long getId() { return id; }
|
public Optional<Long> getId() { return Optional.ofNullable(id); }
|
||||||
public String getName() { return name; }
|
public String getName() { return name; }
|
||||||
public String getDescription() { return description; }
|
public String getDescription() { return description; }
|
||||||
public LocalDate getStartDate() { return startDate; }
|
public LocalDate getStartDate() { return startDate; }
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class TaskTemplate {
|
|||||||
public void setRelativeEndDate(Integer relativeEndDate) {
|
public void setRelativeEndDate(Integer relativeEndDate) {
|
||||||
this.relativeEndDate = relativeEndDate;
|
this.relativeEndDate = relativeEndDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInterval(Integer interval) {
|
public void setInterval(Integer interval) {
|
||||||
this.interval = interval;
|
this.interval = interval;
|
||||||
}
|
}
|
||||||
@@ -45,13 +46,10 @@ public class TaskTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task generateTask(LocalDate realStartDate, long cropId) {
|
public Task generateTask(LocalDate realStartDate, long cropId) {
|
||||||
Task task = new Task(name, description, realStartDate.plusDays(relativeStartDate), cropId);
|
LocalDate endDate = relativeEndDate != null ? realStartDate.plusDays(relativeEndDate) : null;
|
||||||
if (relativeEndDate != null) {
|
|
||||||
task.withEndDate(realStartDate.plusDays(relativeEndDate));
|
return new Task(name, description, realStartDate.plusDays(relativeStartDate), cropId)
|
||||||
}
|
.withInterval(interval)
|
||||||
if (interval != null) {
|
.withEndDate(endDate);
|
||||||
task.withInterval(interval);
|
|
||||||
}
|
|
||||||
return task;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.ListView?>
|
||||||
<?import javafx.scene.control.ScrollPane?>
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
<?import javafx.scene.image.ImageView?>
|
<?import javafx.scene.image.ImageView?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
@@ -12,13 +13,11 @@
|
|||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?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">
|
||||||
<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>
|
<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">
|
<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>
|
<content>
|
||||||
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="503.0" prefWidth="897.0">
|
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="781.0" prefWidth="897.0">
|
||||||
<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" />
|
||||||
</padding>
|
</padding>
|
||||||
@@ -85,22 +84,22 @@
|
|||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</Label>
|
</Label>
|
||||||
<VBox fx:id="growthPhases_vbox" prefHeight="135.0" prefWidth="879.0">
|
<ListView fx:id="taskList_listView" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="877.0" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</VBox>
|
</ListView>
|
||||||
<Button fx:id="editTaskList_button" mnemonicParsing="false" onAction="#editTaskList" prefHeight="25.0" prefWidth="45.0">
|
<Button fx:id="addTask_button" mnemonicParsing="false" onAction="#addTask" prefHeight="25.0" prefWidth="45.0">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</Button>
|
</Button>
|
||||||
<Label text="Pests:" />
|
<Label text="Pests:" />
|
||||||
<VBox fx:id="pests_vbox" prefHeight="200.0" prefWidth="100.0">
|
<ListView fx:id="pests_listView" maxHeight="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
|
||||||
<VBox.margin>
|
<VBox.margin>
|
||||||
<Insets bottom="10.0" />
|
<Insets bottom="10.0" />
|
||||||
</VBox.margin>
|
</VBox.margin>
|
||||||
</VBox>
|
</ListView>
|
||||||
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="NEVER">
|
<HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0" VBox.vgrow="NEVER">
|
||||||
<children>
|
<children>
|
||||||
<Label text="Area:">
|
<Label text="Area:">
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
<Button fx:id="home_button" mnemonicParsing="false" onAction="#goToHome" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||||
<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="myGarden_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMyPlants" prefHeight="38.0" prefWidth="121.0" text="My Garden" />
|
||||||
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
<Button fx:id="mySchedule_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToMySchedule" prefHeight="38.0" prefWidth="121.0" text="My Schedule" />
|
||||||
<Button fx:id="tutorial_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#goToTutorial" prefHeight="38.0" prefWidth="121.0" text="Tutorial" />
|
<Button fx:id="tutorial_button" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#showTutorial" prefHeight="38.0" prefWidth="121.0" text="Tutorial" />
|
||||||
<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" />
|
||||||
<Button fx:id="settings_button" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
<Button fx:id="settings_button" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#openSettings" prefHeight="38.0" prefWidth="40.0" HBox.hgrow="NEVER" />
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.DatePicker?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.TextArea?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
|
||||||
|
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="259.0" prefWidth="390.0" xmlns="http://javafx.com/javafx/17"
|
||||||
|
xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TaskFormularController">
|
||||||
|
<children>
|
||||||
|
<VBox layoutX="14.0" layoutY="14.0" prefHeight="272.0" prefWidth="390.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||||
|
</padding>
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER_LEFT" prefHeight="35.0" prefWidth="560.0">
|
||||||
|
<children>
|
||||||
|
<Label maxWidth="1.7976931348623157E308" text="Task name:" HBox.hgrow="ALWAYS" />
|
||||||
|
<TextField fx:id="taskName_field" promptText="Task Name" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox prefHeight="77.0" prefWidth="350.0">
|
||||||
|
<children>
|
||||||
|
<Label maxWidth="1.7976931348623157E308" text="Description:" HBox.hgrow="ALWAYS" />
|
||||||
|
<TextArea fx:id="description_area" prefHeight="73.0" prefWidth="206.0" promptText="Description" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox alignment="CENTER_LEFT" layoutX="30.0" layoutY="30.0" prefHeight="35.0" prefWidth="560.0">
|
||||||
|
<children>
|
||||||
|
<Label maxWidth="1.7976931348623157E308" text="Start Date:" HBox.hgrow="ALWAYS" />
|
||||||
|
<DatePicker fx:id="start_datePicker" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox alignment="CENTER_LEFT" layoutX="30.0" layoutY="143.0" prefHeight="35.0" prefWidth="560.0">
|
||||||
|
<children>
|
||||||
|
<Label maxWidth="1.7976931348623157E308" text="End Date:" HBox.hgrow="ALWAYS" />
|
||||||
|
<DatePicker fx:id="end_datePicker" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox alignment="CENTER_LEFT" layoutX="30.0" layoutY="30.0" prefHeight="35.0" prefWidth="560.0">
|
||||||
|
<children>
|
||||||
|
<Label maxWidth="1.7976931348623157E308" text="Interval:" HBox.hgrow="ALWAYS" />
|
||||||
|
<TextField fx:id="interval_field" promptText="Interval (e.g. 0, 1, 3 ...)" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
</AnchorPane>
|
||||||
@@ -1,27 +1,141 @@
|
|||||||
<?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.Label?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.layout.AnchorPane?>
|
<?import javafx.scene.control.ButtonBar?>
|
||||||
|
<?import javafx.scene.control.CheckBox?>
|
||||||
|
<?import javafx.scene.control.Separator?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
<?import javafx.scene.text.Text?>
|
||||||
|
<?import javafx.scene.text.TextFlow?>
|
||||||
|
|
||||||
|
<BorderPane maxHeight="470.0" maxWidth="724.0" minHeight="470.0" minWidth="724.0" prefHeight="470.0" prefWidth="724.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController">
|
||||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17"
|
<bottom>
|
||||||
xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.zhaw.gartenverwaltung.TutorialController">
|
<HBox alignment="CENTER" prefHeight="0.0" prefWidth="724.0" BorderPane.alignment="CENTER">
|
||||||
<children>
|
|
||||||
<VBox layoutX="7.0" layoutY="8.0" prefHeight="200.0" prefWidth="100.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
|
||||||
<children>
|
<children>
|
||||||
<Label text="Tutorial">
|
<CheckBox mnemonicParsing="false" text="Don't show again" />
|
||||||
<font>
|
<Separator prefWidth="50.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
<Font size="18.0" />
|
<ButtonBar prefHeight="40.0" prefWidth="200.0">
|
||||||
</font>
|
<buttons>
|
||||||
</Label>
|
<Button cancelButton="true" contentDisplay="CENTER" graphicTextGap="5.0" mnemonicParsing="false" text="Close" onAction="#closeTutorial"/>
|
||||||
<Label text="To be added" />
|
<Button fx:id="previousPageButton" mnemonicParsing="false" text="Previous" onAction="#viewPreviousPage"/>
|
||||||
|
<Button fx:id="nextPageButton" defaultButton="true" mnemonicParsing="false" text="Next" onAction="#viewNextPage" />
|
||||||
|
</buttons>
|
||||||
|
</ButtonBar>
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</VBox>
|
</HBox>
|
||||||
</children>
|
</bottom>
|
||||||
</AnchorPane>
|
<center>
|
||||||
|
<StackPane fx:id="tourPages" prefHeight="150.0" prefWidth="200.0" BorderPane.alignment="CENTER">
|
||||||
|
<children>
|
||||||
|
<VBox layoutX="30.0" layoutY="26.0" opacity="0.0" prefHeight="200.0" prefWidth="100.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Crops">
|
||||||
|
<font>
|
||||||
|
<Font size="24.0" />
|
||||||
|
</font>
|
||||||
|
</Text>
|
||||||
|
<Separator prefWidth="200.0">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="15.0" top="10.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Separator>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="In the "My Garden" tab, you can see all of the plants you're planning on growing.">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Text>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="90.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="To get started, click on the "Add new Plant" button in the bottom left. This will open a list of all the plants you can grow. Use the search bar at the top, the filters on the left, or simply browse the list until you've found a plant you want to grow in your garden." wrappingWidth="345.80316162109375" />
|
||||||
|
</children>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</HBox.margin>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgAddNewPlant" fitHeight="98.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Once you've found what you're looking for, click the "Select Sow/Harvest Date" button at the bottom of the window. In the subsequently shown dialog, you can select the date you'd like to sow or harvest the crop. The date selector shows possible dates in green. Confirm your selection with the "Save" button." />
|
||||||
|
</children>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgSelectDate" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
</children>
|
||||||
|
<opaqueInsets>
|
||||||
|
<Insets />
|
||||||
|
</opaqueInsets>
|
||||||
|
</VBox>
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Managing Your Tasks">
|
||||||
|
<font>
|
||||||
|
<Font size="24.0" />
|
||||||
|
</font>
|
||||||
|
</Text>
|
||||||
|
<Separator prefWidth="200.0">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="15.0" top="10.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Separator>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="In the "My Schedule" tab, you can see all of the tasks you need to complete for a successful harvest.">
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Text>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="90.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="You can view the tasks for a specific crop by selecting it from the left sidebar. To see all tasks again, click the "Clear Filter" button at the bottom." wrappingWidth="345.80316162109375" />
|
||||||
|
</children>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets bottom="20.0" />
|
||||||
|
</HBox.margin>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fx:id="imgTaskList" fitHeight="98.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<HBox prefHeight="100.0" prefWidth="200.0">
|
||||||
|
<children>
|
||||||
|
<TextFlow lineSpacing="4.0" prefHeight="200.0" prefWidth="500.0">
|
||||||
|
<children>
|
||||||
|
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="You can also add your own custom tasks, by clicking the "Add Task" button. In the subsequently shown dialog, you can enter the corresponding details. Note: If you want to make a task recurring, you need to set both an interval (in days) AND an end date, so the task won't repeat for all eternity." />
|
||||||
|
</children>
|
||||||
|
</TextFlow>
|
||||||
|
<Separator prefWidth="200.0" visible="false" HBox.hgrow="ALWAYS" />
|
||||||
|
<ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
|
</children></HBox>
|
||||||
|
</children>
|
||||||
|
<opaqueInsets>
|
||||||
|
<Insets />
|
||||||
|
</opaqueInsets>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
<BorderPane.margin>
|
||||||
|
<Insets />
|
||||||
|
</BorderPane.margin>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||||
|
</padding>
|
||||||
|
</StackPane>
|
||||||
|
</center>
|
||||||
|
</BorderPane>
|
||||||
|
|||||||
@@ -184,15 +184,14 @@
|
|||||||
"litersPerSqM": 15,
|
"litersPerSqM": 15,
|
||||||
"interval": 4,
|
"interval": 4,
|
||||||
"notes": [
|
"notes": [
|
||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"taskTemplates": [
|
"taskTemplates": [
|
||||||
{
|
{
|
||||||
"name": "hilling",
|
"name": "Plant Sets",
|
||||||
"relativeStartDate": 0,
|
"relativeStartDate": 0,
|
||||||
"relativeEndDate": 0,
|
"relativeEndDate": 0,
|
||||||
"description": "Mound up the soil around the plant until just the top few leaves show above the soil. ",
|
"description": "Plant the sets about 5cm deep into the soil.",
|
||||||
"interval": null,
|
"interval": null,
|
||||||
"isOptional": false
|
"isOptional": false
|
||||||
}
|
}
|
||||||
@@ -232,7 +231,6 @@
|
|||||||
"litersPerSqM": 0,
|
"litersPerSqM": 0,
|
||||||
"interval": null,
|
"interval": null,
|
||||||
"notes": [
|
"notes": [
|
||||||
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"taskTemplates": [
|
"taskTemplates": [
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"id" : 1,
|
"id": 1,
|
||||||
"name" : "sow plant",
|
"name": "sow plant",
|
||||||
"description": "Plant the seeds, crops in de bed.",
|
"description": "Plant the seeds, crops in de bed.",
|
||||||
"startDate" : "2022-05-01",
|
"startDate": "2022-05-01",
|
||||||
"endDate" : "2022-05-01",
|
"endDate": "2022-05-01",
|
||||||
"interval" : 0,
|
"interval": 0,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 2,
|
"id": 2,
|
||||||
"name" : "water plant",
|
"name": "water plant",
|
||||||
"description": "water the plant, so that the soil is wet around the plant.",
|
"description": "water the plant, so that the soil is wet around the plant.",
|
||||||
"startDate" : "2022-05-01",
|
"startDate": "2022-05-01",
|
||||||
"endDate" : "2022-09-01",
|
"endDate": "2022-09-01",
|
||||||
"interval" : 2,
|
"interval": 2,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 3,
|
"id": 3,
|
||||||
"name" : "fertilize plant",
|
"name": "fertilize plant",
|
||||||
"description": "The fertilizer has to be mixed with water. Then fertilize the plants soil with the mixture",
|
"description": "The fertilizer has to be mixed with water. Then fertilize the plants soil with the mixture",
|
||||||
"startDate" : "2022-06-01",
|
"startDate": "2022-06-01",
|
||||||
"endDate" : "2022-08-01",
|
"endDate": "2022-08-01",
|
||||||
"interval" : 28,
|
"interval": 28,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 4,
|
"id": 4,
|
||||||
"name" : "covering plant",
|
"name": "covering plant",
|
||||||
"description": "Take a big enough coverage for the plants. Cover the whole plant with a bit space between the plant and the coverage",
|
"description": "Take a big enough coverage for the plants. Cover the whole plant with a bit space between the plant and the coverage",
|
||||||
"startDate" : "2022-07-01",
|
"startDate": "2022-07-01",
|
||||||
"endDate" : "2022-07-01",
|
"endDate": "2022-07-01",
|
||||||
"interval" : 0,
|
"interval": 0,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 5,
|
"id": 5,
|
||||||
"name" : "look after plant",
|
"name": "look after plant",
|
||||||
"description": "Look for pest or illness at the leaves of the plant. Check the soil around the plant, if the roots are enough covered with soil",
|
"description": "Look for pest or illness at the leaves of the plant. Check the soil around the plant, if the roots are enough covered with soil",
|
||||||
"startDate" : "2022-05-01",
|
"startDate": "2022-05-01",
|
||||||
"endDate" : "2022-09-01",
|
"endDate": "2022-09-01",
|
||||||
"interval" : 5,
|
"interval": 5,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 6,
|
"id": 6,
|
||||||
"name" : "harvest plant",
|
"name": "harvest plant",
|
||||||
"description": "Pull the ripe vegetables out from the soil. Clean them with clear, fresh water. ",
|
"description": "Pull the ripe vegetables out from the soil. Clean them with clear, fresh water. ",
|
||||||
"startDate" : "2022-09-01",
|
"startDate": "2022-09-01",
|
||||||
"endDate" : "2022-09-01",
|
"endDate": "2022-09-01",
|
||||||
"interval" : 0,
|
"interval": 0,
|
||||||
"cropId" : 0
|
"cropId": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -72,7 +72,8 @@ public class JsonTaskListTest {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Remove task.")
|
@DisplayName("Remove task.")
|
||||||
void removeTask() {
|
void removeTask() {
|
||||||
Task task = new Task("Dummy", "Dummy", LocalDate.parse("2022-05-31", formatter), 1).withId(2);
|
Task task = new Task("Dummy", "Dummy", LocalDate.parse("2022-05-31", formatter), 1)
|
||||||
|
.withId(2);
|
||||||
try {
|
try {
|
||||||
testDatabase.removeTask(task);
|
testDatabase.removeTask(task);
|
||||||
List<Task> taskList;
|
List<Task> taskList;
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ public class GardenPlanModelTest {
|
|||||||
new GrowthPhase(MonthDay.of(2, 8), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()),
|
new GrowthPhase(MonthDay.of(2, 8), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>()),
|
||||||
new GrowthPhase(MonthDay.of(10, 2), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));
|
new GrowthPhase(MonthDay.of(10, 2), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));
|
||||||
|
|
||||||
exampleCropOnion = new Crop(examplePlantOnion.id(), LocalDate.of(2023,3,1));
|
exampleCropOnion = new Crop(examplePlantOnion.id(), LocalDate.of(2023, 3, 1))
|
||||||
exampleCropOnion.withId(3);
|
.withId(3);
|
||||||
examplePlantCarrot = new Plant(
|
examplePlantCarrot = new Plant(
|
||||||
1,
|
1,
|
||||||
"Early Carrot",
|
"Early Carrot",
|
||||||
@@ -67,18 +67,18 @@ public class GardenPlanModelTest {
|
|||||||
"sandy to loamy, loose soil, free of stones",
|
"sandy to loamy, loose soil, free of stones",
|
||||||
new ArrayList<>(),
|
new ArrayList<>(),
|
||||||
List.of(new GrowthPhase(MonthDay.of(4, 4), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));
|
List.of(new GrowthPhase(MonthDay.of(4, 4), MonthDay.of(12, 4), 0, new WateringCycle(0, 0, null), GrowthPhaseType.PLANT, HardinessZone.ZONE_8A, new ArrayList<>())));
|
||||||
exampleCropCarrot = new Crop(examplePlantCarrot.id(), LocalDate.now());
|
exampleCropCarrot = new Crop(examplePlantCarrot.id(), LocalDate.now())
|
||||||
exampleCropCarrot.withId(5);
|
.withId(5);
|
||||||
|
|
||||||
exampleCrop1 = new Crop(1, LocalDate.of(2023,2,25));
|
exampleCrop1 = new Crop(1, LocalDate.of(2023, 2, 25))
|
||||||
exampleCrop1.withId(0);
|
.withId(0)
|
||||||
exampleCrop1.withArea(0.5);
|
.withArea(0.5);
|
||||||
exampleCrop2 = new Crop(1,LocalDate.of(2023,3,1));
|
exampleCrop2 = new Crop(1, LocalDate.of(2023, 3, 1))
|
||||||
exampleCrop2.withId(1);
|
.withId(1)
|
||||||
exampleCrop2.withArea(0.5);
|
.withArea(0.5);
|
||||||
exampleCrop3 = new Crop(0,LocalDate.of(2023,3,1));
|
exampleCrop3 = new Crop(0, LocalDate.of(2023, 3, 1))
|
||||||
exampleCrop3.withId(2);
|
.withId(2)
|
||||||
exampleCrop3.withArea(1.0);
|
.withArea(1.0);
|
||||||
|
|
||||||
exampleCrops = new ArrayList<>();
|
exampleCrops = new ArrayList<>();
|
||||||
exampleCrops.add(exampleCrop1);
|
exampleCrops.add(exampleCrop1);
|
||||||
@@ -107,7 +107,7 @@ public class GardenPlanModelTest {
|
|||||||
@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);
|
Optional<Crop> exampleCrop = model.getCrop(2L);
|
||||||
assertTrue(exampleCrop.isPresent());
|
assertTrue(exampleCrop.isPresent());
|
||||||
assertEquals(model.getCrops().get(2), exampleCrop.get());
|
assertEquals(model.getCrops().get(2), exampleCrop.get());
|
||||||
@@ -119,6 +119,6 @@ public class GardenPlanModelTest {
|
|||||||
exampleCrop1.withId(2);
|
exampleCrop1.withId(2);
|
||||||
exampleCrop1.withArea(1.5);
|
exampleCrop1.withArea(1.5);
|
||||||
model.removeCrop(exampleCrop1);
|
model.removeCrop(exampleCrop1);
|
||||||
assertEquals(2,model.getCrops().size());
|
assertEquals(2, model.getCrops().size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user