1+ package root .javafx .DI ;
2+
3+ import java .io .IOException ;
4+ import java .lang .reflect .InvocationTargetException ;
5+ import java .util .HashMap ;
6+ import java .util .Map ;
7+ import java .util .ResourceBundle ;
8+
9+ import javafx .fxml .FXMLLoader ;
10+ import javafx .fxml .JavaFXBuilderFactory ;
11+ import javafx .scene .Parent ;
12+ import javafx .util .Callback ;
13+
14+ public class DependencyInjection {
15+
16+ /**
17+ * A map of all Controllers that can be injected, and the methods responsible
18+ * for doing so.
19+ */
20+ private static final Map <Class <?>, Callback <Class <?>, Object >> injectionMethods = new HashMap <>();
21+ private static ResourceBundle bundle = null ;
22+
23+ public static Parent load (String location ) throws IOException {
24+ FXMLLoader loader = getLoader (location );
25+ return loader .load ();
26+ }
27+
28+ public static FXMLLoader getLoader (String location ) {
29+ return new FXMLLoader (DependencyInjection .class .getResource (location ), bundle , new JavaFXBuilderFactory (),
30+ controllerClass -> constructController (controllerClass ));
31+ }
32+
33+ public static void setBundle (ResourceBundle bundle ) {
34+ DependencyInjection .bundle = bundle ;
35+ }
36+
37+ public static void addInjectionMethod (Class <?> controller , Callback <Class <?>, Object > method ) {
38+ injectionMethods .put (controller , method );
39+ }
40+
41+ public static void removeInjectionMethod (Class <?> controller ) {
42+ injectionMethods .remove (controller );
43+ }
44+
45+ /**
46+ * Determine whether a stored method is available If one is, return the custom
47+ * controller If one is not, return the default controller
48+ *
49+ * @param controllerClass the class of controller to be created
50+ * @return the controller created
51+ */
52+ private static Object constructController (Class <?> controllerClass ) {
53+ if (injectionMethods .containsKey (controllerClass )) {
54+ return loadControllerWithSavedMethod (controllerClass );
55+ } else {
56+ return loadControllerWithDefaultConstructor (controllerClass );
57+ }
58+ }
59+
60+ /**
61+ * Load a controller using the saved method
62+ *
63+ * @param controller the class of the controller to be loaded
64+ * @return the loaded controller
65+ */
66+ private static Object loadControllerWithSavedMethod (Class <?> controller ) {
67+ try {
68+ return injectionMethods .get (controller ).call (controller );
69+ } catch (Exception e ) {
70+ throw new IllegalStateException (e );
71+ }
72+ }
73+
74+ private static Object loadControllerWithDefaultConstructor (Class <?> controller ) {
75+ try {
76+ return controller .getConstructor ().newInstance ();
77+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException
78+ | NoSuchMethodException e ) {
79+ throw new IllegalStateException (e );
80+ }
81+ }
82+ }
0 commit comments