320 lines
12 KiB
Java
320 lines
12 KiB
Java
package ch.zhaw.gartenverwaltung;
|
|
|
|
import ch.zhaw.gartenverwaltung.bootstrap.AfterInject;
|
|
import ch.zhaw.gartenverwaltung.bootstrap.AppLoader;
|
|
import ch.zhaw.gartenverwaltung.bootstrap.ChangeViewEvent;
|
|
import ch.zhaw.gartenverwaltung.bootstrap.Inject;
|
|
import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException;
|
|
import ch.zhaw.gartenverwaltung.models.Garden;
|
|
import ch.zhaw.gartenverwaltung.models.PlantListModel;
|
|
import ch.zhaw.gartenverwaltung.models.PlantNotFoundException;
|
|
import ch.zhaw.gartenverwaltung.types.HardinessZone;
|
|
import ch.zhaw.gartenverwaltung.types.Plant;
|
|
import ch.zhaw.gartenverwaltung.types.Seasons;
|
|
import javafx.beans.property.ListProperty;
|
|
import javafx.beans.property.SimpleListProperty;
|
|
import javafx.collections.FXCollections;
|
|
import javafx.fxml.FXML;
|
|
import javafx.geometry.Insets;
|
|
import javafx.scene.control.*;
|
|
import javafx.scene.image.Image;
|
|
import javafx.scene.image.ImageView;
|
|
import javafx.scene.layout.AnchorPane;
|
|
import javafx.scene.layout.VBox;
|
|
|
|
import java.io.IOException;
|
|
import java.time.LocalDate;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
/**
|
|
* Controller class for the Plants.fxml file
|
|
*/
|
|
public class PlantsController {
|
|
private static final Logger LOG = Logger.getLogger(PlantsController.class.getName());
|
|
|
|
@Inject
|
|
private PlantListModel plantListModel;
|
|
@Inject
|
|
private AppLoader appLoader;
|
|
@Inject
|
|
private Garden garden;
|
|
|
|
private Plant selectedPlant = null;
|
|
private final HardinessZone DEFAULT_HARDINESS_ZONE = HardinessZone.ZONE_8A;
|
|
|
|
private final ListProperty<Plant> plantListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
|
|
|
|
@FXML
|
|
public AnchorPane plantsRoot;
|
|
|
|
@FXML
|
|
private VBox seasons;
|
|
|
|
@FXML
|
|
private VBox climate_zones;
|
|
|
|
@FXML
|
|
private Label description_plant;
|
|
|
|
@FXML
|
|
private ImageView img_plant;
|
|
|
|
@FXML
|
|
private ListView<Plant> list_plants;
|
|
|
|
@FXML
|
|
private Button selectSowDay_button;
|
|
|
|
@FXML
|
|
private TextField search_plants;
|
|
|
|
/**
|
|
* open new window to select sow or harvest day to save the crop
|
|
*/
|
|
@FXML
|
|
void selectSowDate() throws IOException {
|
|
Dialog<LocalDate> dateSelection = new Dialog<>();
|
|
dateSelection.setTitle("Select Date");
|
|
dateSelection.setHeaderText(String.format("Select Harvest/Sow Date for %s:", selectedPlant.name()));
|
|
dateSelection.setResizable(false);
|
|
|
|
DialogPane dialogPane = dateSelection.getDialogPane();
|
|
|
|
dialogPane.getStylesheets().add(
|
|
Objects.requireNonNull(getClass().getResource("bootstrap/dialogStyle.css")).toExternalForm());
|
|
dialogPane.getStyleClass().add("myDialog");
|
|
|
|
ButtonType sowButton = new ButtonType("Save", ButtonBar.ButtonData.OK_DONE);
|
|
dialogPane.getButtonTypes().addAll(sowButton, ButtonType.CANCEL);
|
|
|
|
if (appLoader.loadPaneToDialog("SelectSowDay.fxml", dialogPane) instanceof SelectSowDayController controller) {
|
|
controller.initSaveButton((Button) dialogPane.lookupButton(sowButton));
|
|
controller.setSelectedPlant(selectedPlant);
|
|
dateSelection.setResultConverter(button -> button.equals(sowButton) ? controller.retrieveResult() : null);
|
|
|
|
dateSelection.showAndWait()
|
|
.ifPresent(date -> {
|
|
try {
|
|
garden.plantAsCrop(selectedPlant, date);
|
|
} catch (IOException | HardinessZoneNotSetException | PlantNotFoundException e) {
|
|
LOG.log(Level.SEVERE, "Couldn't save Crop", e);
|
|
}
|
|
plantsRoot.fireEvent(new ChangeViewEvent(ChangeViewEvent.CHANGE_MAIN_VIEW, "MyGarden.fxml"));
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* fill list view with current hardiness zone
|
|
* set default values
|
|
* create filter of season and hardiness zone
|
|
* create event listener for selected list entry and search by query
|
|
* {@inheritDoc}
|
|
*/
|
|
@AfterInject
|
|
@SuppressWarnings("unused")
|
|
public void init() {
|
|
setListCellFactory();
|
|
fillPlantListWithHardinessZone();
|
|
list_plants.itemsProperty().bind(plantListProperty);
|
|
|
|
description_plant.setText("");
|
|
selectSowDay_button.setDisable(true);
|
|
|
|
createFilterSeasons();
|
|
createFilterHardinessZone();
|
|
lookForSelectedListEntry();
|
|
|
|
try {
|
|
viewFilteredListBySearch();
|
|
} catch (HardinessZoneNotSetException e) {
|
|
LOG.log(Level.WARNING, "Hardiness Zone not set!");
|
|
} catch (IOException e) {
|
|
LOG.log(Level.WARNING, "Could not retrieve data!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* set text of list view to plant name
|
|
*/
|
|
private void setListCellFactory() {
|
|
list_plants.setCellFactory(param -> new ListCell<>() {
|
|
@Override
|
|
protected void updateItem(Plant plant, boolean empty) {
|
|
super.updateItem(plant, empty);
|
|
|
|
if (empty || plant == null || plant.name() == null) {
|
|
setText(null);
|
|
} else {
|
|
setText(plant.name());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* get plant list according to param season and hardiness zone
|
|
* fill list view with plant list
|
|
*
|
|
* @param season enum of seasons
|
|
* @throws HardinessZoneNotSetException throws exception
|
|
* @throws IOException throws exception
|
|
*/
|
|
private void viewFilteredListBySeason(Seasons season) throws HardinessZoneNotSetException, IOException {
|
|
clearListView();
|
|
plantListProperty.addAll(plantListModel.getFilteredPlantListBySaisonWithoutGrowthPhase(plantListModel.getCurrentZone(), season.getStartDate(), season.getEndDate()));
|
|
}
|
|
|
|
/**
|
|
* get plant list filtered by search plant entry and hardiness zone
|
|
* fill list view with plant list
|
|
*
|
|
* @throws HardinessZoneNotSetException throws exception when no hardiness zone is defined
|
|
* @throws IOException throws exception
|
|
*/
|
|
private void viewFilteredListBySearch() throws HardinessZoneNotSetException, IOException {
|
|
search_plants.textProperty().addListener((observable, oldValue, newValue) -> {
|
|
if (newValue.isEmpty()) {
|
|
fillPlantListWithHardinessZone();
|
|
} else {
|
|
try {
|
|
List<Plant> filteredPlants = plantListModel.getFilteredPlantListByString(DEFAULT_HARDINESS_ZONE, newValue);
|
|
clearListView();
|
|
plantListProperty.addAll(filteredPlants);
|
|
} catch (HardinessZoneNotSetException e) {
|
|
LOG.log(Level.WARNING, "Hardiness Zone not set!");
|
|
} catch (IOException e) {
|
|
LOG.log(Level.WARNING, "Could not retrieve data!", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* get plant list of current hardiness zone
|
|
* fill list view with plant list
|
|
*/
|
|
private void fillPlantListWithHardinessZone() {
|
|
try {
|
|
clearListView();
|
|
plantListProperty.addAll(plantListModel.getPlantList(plantListModel.getCurrentZone()));
|
|
} catch (HardinessZoneNotSetException e) {
|
|
LOG.log(Level.WARNING, "Hardiness Zone not set!");
|
|
} catch (IOException e) {
|
|
LOG.log(Level.WARNING, "Could not retrieve data!", e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* creates radio buttons for the hardiness zones defined in enum HardinessZone
|
|
* defines default value as selected
|
|
* when selected filter viewList according to hardiness zone
|
|
*/
|
|
private void createFilterHardinessZone() {
|
|
ToggleGroup hardinessGroup = new ToggleGroup();
|
|
for (HardinessZone zone : HardinessZone.values()) {
|
|
RadioButton radioButton = new RadioButton(zone.name());
|
|
radioButton.setToggleGroup(hardinessGroup);
|
|
radioButton.setPadding(new Insets(0, 0, 10, 0));
|
|
if (zone.equals(DEFAULT_HARDINESS_ZONE)) {
|
|
radioButton.setSelected(true);
|
|
}
|
|
radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
|
plantListModel.setCurrentZone(zone);
|
|
fillPlantListWithHardinessZone();
|
|
});
|
|
climate_zones.getChildren().add(radioButton);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* creates radio buttons for the seasons defined in enum Seasons
|
|
* defines default value as selected
|
|
* when selected filter viewList according to seasons
|
|
*/
|
|
private void createFilterSeasons() {
|
|
ToggleGroup seasonGroup = new ToggleGroup();
|
|
for (Seasons season : Seasons.values()) {
|
|
RadioButton radioButton = new RadioButton(season.getName());
|
|
radioButton.setToggleGroup(seasonGroup);
|
|
radioButton.setPadding(new Insets(0, 0, 10, 0));
|
|
if (season.equals(Seasons.ALLSEASONS)) {
|
|
radioButton.setSelected(true);
|
|
}
|
|
radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
|
if (season.equals(Seasons.ALLSEASONS)) {
|
|
fillPlantListWithHardinessZone();
|
|
} else {
|
|
try {
|
|
viewFilteredListBySeason(season);
|
|
} catch (HardinessZoneNotSetException e) {
|
|
LOG.log(Level.WARNING, "Hardiness Zone not set!");
|
|
} catch (IOException e) {
|
|
LOG.log(Level.WARNING, "Could not retrieve data!", e);
|
|
}
|
|
}
|
|
|
|
});
|
|
seasons.getChildren().add(radioButton);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* observes changes in the selectedProperty of ListView and updates:
|
|
* the description label
|
|
* image of the plant
|
|
*/
|
|
private void lookForSelectedListEntry() {
|
|
selectedPlant = null;
|
|
description_plant.setText("");
|
|
selectSowDay_button.setDisable(true);
|
|
Image img = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
|
img_plant.setImage(img);
|
|
list_plants.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
|
|
if (newValue != null) {
|
|
selectedPlant = newValue;
|
|
description_plant.setText(getPlantDescription());
|
|
selectSowDay_button.setDisable(false);
|
|
Image img1;
|
|
if (selectedPlant.image() != null) {
|
|
img1 = selectedPlant.image();
|
|
} else {
|
|
img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
|
}
|
|
img_plant.setImage(img1);
|
|
} else {
|
|
selectedPlant = null;
|
|
description_plant.setText("");
|
|
selectSowDay_button.setDisable(true);
|
|
Image img1 = new Image(String.valueOf(PlantsController.class.getResource("placeholder.png")));
|
|
img_plant.setImage(img1);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
private void clearListView() {
|
|
plantListProperty.clear();
|
|
}
|
|
}
|