refactor: first attempt at dependency injection

also some more renaming and improving date-picker dialog
This commit is contained in:
David Guler
2022-11-14 20:00:01 +01:00
parent 4f80a0a3e0
commit 15279838b7
14 changed files with 378 additions and 333 deletions
@@ -1,17 +1,35 @@
package ch.zhaw.gartenverwaltung;
import ch.zhaw.gartenverwaltung.io.CropList;
import ch.zhaw.gartenverwaltung.io.JsonCropList;
import ch.zhaw.gartenverwaltung.io.JsonPlantList;
import ch.zhaw.gartenverwaltung.io.JsonTaskList;
import ch.zhaw.gartenverwaltung.io.PlantList;
import ch.zhaw.gartenverwaltung.io.TaskList;
import ch.zhaw.gartenverwaltung.models.Garden;
import ch.zhaw.gartenverwaltung.models.GardenSchedule;
import ch.zhaw.gartenverwaltung.models.PlantListModel;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -20,9 +38,16 @@ public class MainFXMLController implements Initializable {
/**
* Caching the panes
*/
private final Map<String, AnchorPane> panes = new HashMap<>();
private final Map<String, Pane> panes = new HashMap<>();
private static final Logger LOG = Logger.getLogger(MainFXMLController.class.getName());
private final PlantList plantList = new JsonPlantList();
private final CropList cropList = new JsonCropList();
private final TaskList taskList = new JsonTaskList();
private final GardenSchedule gardenSchedule = new GardenSchedule(taskList, plantList);
private final Garden garden = new Garden(gardenSchedule, cropList);
@FXML
private Button home_button;
@@ -30,7 +55,7 @@ public class MainFXMLController implements Initializable {
private AnchorPane mainPane;
@FXML
private Button myPlants_button;
private Button myGarden_button;
@FXML
private Button mySchedule_button;
@@ -38,27 +63,30 @@ public class MainFXMLController implements Initializable {
@FXML
private Button plants_button;
public MainFXMLController() throws IOException {
}
@FXML
void goToHome(ActionEvent event) throws IOException {
loadPane("Home.fxml");
showPaneAsMainView("Home.fxml");
styleChangeButton(home_button);
}
@FXML
void goToMyPlants(ActionEvent event) throws IOException {
loadPane("MyPlants.fxml");
styleChangeButton(myPlants_button);
showPaneAsMainView("MyGarden.fxml");
styleChangeButton(myGarden_button);
}
@FXML
void goToMySchedule(ActionEvent event) throws IOException {
loadPane("MySchedule.fxml");
showPaneAsMainView("MySchedule.fxml");
styleChangeButton(mySchedule_button);
}
@FXML
void goToPlants(ActionEvent event) throws IOException {
loadPane("Plants.fxml");
showPaneAsMainView("Plants.fxml");
styleChangeButton(plants_button);
}
@@ -69,23 +97,68 @@ public class MainFXMLController implements Initializable {
* @param fxmlFile string of fxml file
* @throws IOException exception when file does not exist
*/
public void loadPane(String fxmlFile) throws IOException {
AnchorPane anchorPane = panes.get(fxmlFile);
public void showPaneAsMainView(String fxmlFile) throws IOException {
Pane anchorPane = panes.get(fxmlFile);
if (anchorPane == null) {
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
anchorPane = loader.load();
panes.put(fxmlFile, anchorPane);
if(fxmlFile.equals("MyPlants.fxml")) {
MyPlantsController myPlantsController = loader.getController();
myPlantsController.getMainController(this);
}
loadAndCacheFxml(fxmlFile);
anchorPane = panes.get(fxmlFile);
}
mainPane.getChildren().setAll(anchorPane);
anchorPane.prefWidthProperty().bind(mainPane.widthProperty());
anchorPane.prefHeightProperty().bind(mainPane.heightProperty());
}
public Object loadSceneToStage(String fxmlFile, Stage appendee) throws IOException {
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
Pane root = loader.load();
appendee.setScene(new Scene(root));
Object controller = loader.getController();
injectDependencies(controller);
return controller;
}
public FXMLLoader loadAndCacheFxml(String fxmlFile) throws IOException {
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(HelloApplication.class.getResource(fxmlFile)));
AnchorPane anchorPane = loader.load();
panes.put(fxmlFile, anchorPane);
injectDependencies(loader.getController());
return loader;
}
public void injectDependencies(Object controller) {
Optional<Method> injectMethod = Arrays.stream(controller.getClass().getMethods())
.filter(method -> method.getName().equals("injectDependencies") )
.findFirst();
if (injectMethod.isPresent()) {
Method injectee = injectMethod.get();
List<Object> params = new ArrayList<>();
for (Class<?> parameterType : injectee.getParameterTypes()) {
Object toInject = switch (parameterType.getSimpleName()) {
case "Garden" -> garden;
case "PlantList" -> plantList;
case "PlantListModel" -> new PlantListModel(plantList);
case "GardenSchedule" -> gardenSchedule;
case "MainFXMLController" -> this;
default -> null;
};
if (toInject != null) {
params.add(toInject);
}
}
try {
injectee.invoke(controller, params.toArray());
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
private void preloadPanes() throws IOException {
loadAndCacheFxml("MyGarden.fxml");
loadAndCacheFxml("MySchedule.fxml");
loadAndCacheFxml("Plants.fxml").getController();
}
private void styleChangeButton(Button button) {
@@ -99,7 +172,8 @@ public class MainFXMLController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
try {
loadPane("Home.fxml");
preloadPanes();
showPaneAsMainView("Home.fxml");
styleChangeButton(home_button);
} catch (IOException e) {
LOG.log(Level.SEVERE, "Failed to load FXML-Pane!", e);