I'd be interested in the groups opinions... From http://stackoverflow.com/questions/28741472/integrating-spring-with-fxml-nested-controllers
I'm implementing a large application using JavaFX but unsure how to deal with nested controllers and Spring. * The FXML has already been provided by the design team and has up to 3 levels of nested FXML using the include mechanism. * Models will be defined in Spring * I need to inject the models into all the nested controllers * There are multiple instances of controllers of the same type. i.e. parts of the screen are identical but powered by different instances of the same model type. My work so far -------------- * I've read [Stephen Chin's blog - JavaFX in Spring Day 2 Configuration and FXML][1] and other SO questions however these only deals with top level controllers. * I experimented with FXMLLoader.setControllerFactory() mechanism and defining the controllers in the application context, however this only gives the class of the controller to create, which means there is no way to differentiate the two controllers of the same type but with different data. Problem with using controller factory: loader.setControllerFactory(new Callback<Class<?>, Object>() { @Override public Object call(Class<?> param) { // OK but doesn't work when multiple instances controller of same type return context.getBean(param); } }); * My best approach so far is for the top level controller to be wired up using Stephen Chin approach. * For the case with multiple bean instances the parent controller will get references to the specific beans via @Autowire/@Qualifer and then set on the corresponding controller. * The next level of controllers can be wired up too by exposing them on the top level controller and calling autowire() Specific questions ------------------ * Is there anyway of using controller factory mechanism so I can define the controllers in the spring context instead so that it is easier to wire them up ? * Is there some other method I can use? Example ------- Spring context <context:annotation-config /> <bean id="modelA" class="org.example.Model"> <property name="value" value="a value" /> </bean> <bean id="modelB" class="org.example.Model"> <property name="value" value="b value" /> </bean> Top level <HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.TopLevelController"> <children> <TabPane tabClosingPolicy="UNAVAILABLE"> <tabs> <Tab text="A"> <content> <fx:include fx:id="a" source="nested.fxml" /> </content> </Tab> <Tab text="B"> <content> <fx:include fx:id="b" source="nested.fxml" /> </content> </Tab> </tabs> </TabPane> </children> </HBox> Nested level <HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.NestedController"> <children> <TextField fx:id="value" /> </children> </HBox> Application main public class NestedControllersSpring extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/app-context.xml"); FXMLLoader loader = new FXMLLoader(getClass().getResource("/top-level.fxml")); stage.setScene(new Scene(loader.load())); TopLevelController top = loader.getController(); context.getAutowireCapableBeanFactory().autowireBean(top); context.getAutowireCapableBeanFactory().autowireBean(top.getAController()); context.getAutowireCapableBeanFactory().autowireBean(top.getBController()); top.init(); // needed because autowire doesn't call @PostConstruct stage.show(); } } Top level controller public class TopLevelController { @FXML private NestedController aController; @FXML private NestedController bController; @Autowired @Qualifier("modelA") private Model a; @Autowired @Qualifier("modelB") private Model b; @PostConstruct public void init() { aController.setModel(a); bController.setModel(b); } public NestedController getAController() { return aController; } public NestedController getBController() { return bController; } } [1]: http://steveonjava.com/javafx-in-spring-day-2/