refactor: annotation-based dependency-injection

This commit is contained in:
David Guler
2022-11-14 21:15:27 +01:00
parent 15279838b7
commit 5ef3f6c587
9 changed files with 188 additions and 139 deletions
@@ -1,53 +1,21 @@
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 ch.zhaw.gartenverwaltung.bootstrap.AppLoader;
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;
public class MainFXMLController implements Initializable {
/**
* Caching the panes
*/
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);
private final AppLoader appLoader = new AppLoader(this);
@FXML
private Button home_button;
@@ -67,25 +35,25 @@ public class MainFXMLController implements Initializable {
}
@FXML
void goToHome(ActionEvent event) throws IOException {
void goToHome() throws IOException {
showPaneAsMainView("Home.fxml");
styleChangeButton(home_button);
}
@FXML
void goToMyPlants(ActionEvent event) throws IOException {
void goToMyPlants() throws IOException {
showPaneAsMainView("MyGarden.fxml");
styleChangeButton(myGarden_button);
}
@FXML
void goToMySchedule(ActionEvent event) throws IOException {
void goToMySchedule() throws IOException {
showPaneAsMainView("MySchedule.fxml");
styleChangeButton(mySchedule_button);
}
@FXML
void goToPlants(ActionEvent event) throws IOException {
void goToPlants() throws IOException {
showPaneAsMainView("Plants.fxml");
styleChangeButton(plants_button);
}
@@ -98,67 +66,17 @@ public class MainFXMLController implements Initializable {
* @throws IOException exception when file does not exist
*/
public void showPaneAsMainView(String fxmlFile) throws IOException {
Pane anchorPane = panes.get(fxmlFile);
if (anchorPane == null) {
loadAndCacheFxml(fxmlFile);
anchorPane = panes.get(fxmlFile);
}
Pane anchorPane = appLoader.loadPane(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();
appLoader.loadAndCacheFxml("MyGarden.fxml");
appLoader.loadAndCacheFxml("MySchedule.fxml");
appLoader.loadAndCacheFxml("Plants.fxml");
}
private void styleChangeButton(Button button) {