Merge branch 'dev' into feature_taskList_m2
This commit is contained in:
@@ -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<Task> taskListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||
private final ListProperty<Pest> 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<Task> taskList_listView;
|
||||
|
||||
@FXML
|
||||
private ListView<Pest> 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<Task> 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<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);
|
||||
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<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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ButtonType> 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<ChangeViewEvent> 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Crop> 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<Crop> 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<ActionEvent> 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<ActionEvent> 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.");
|
||||
|
||||
|
||||
@@ -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<Plant> 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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<HardinessZone> 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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package ch.zhaw.gartenverwaltung;
|
||||
|
||||
|
||||
public class TutorialController {
|
||||
|
||||
}
|
||||
@@ -53,6 +53,7 @@ public class JsonCropList implements CropList {
|
||||
public JsonCropList(URL dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@@ -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<Long, Plant> 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}.
|
||||
|
||||
@@ -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<Long, Task> 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) -> {});
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Long> getId() { return Optional.ofNullable(id); }
|
||||
public String getName() { return name; }
|
||||
public String getDescription() { return description; }
|
||||
public LocalDate getStartDate() { return startDate; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user