Я прошел ряд учебных пособий по интеграции Spring DI с JavaFx, но я ударил стену, что простые примеры не покрывают (и я не могу понять).
Я хочу чистое разделение между слоями представления и представления. Я хотел бы использовать fxml для определения композиционных представлений и Spring, чтобы связать все это вместе. Вот конкретный пример:
Dashboard.fxml:
<GridPane fx:id="view"
fx:controller="com.scrub.presenters.DashboardPresenter"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml">
<children>
<TransactionHistoryPresenter fx:id="transactionHistory" />
</children>
</GridPane>
Main.java:
public void start(Stage primaryStage) throws Exception{
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppFactory.class);
SpringFxmlLoader loader = context.getBean(SpringFxmlLoader.class);
primaryStage.setScene(new Scene((Parent)loader.load("/views/dashboard.fxml")));
primaryStage.setTitle("Hello World");
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
SpringFxmlLoader.java:
public class SpringFxmlLoader {
@Autowired
ApplicationContext context;
public Object load(String url) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource(url));
loader.setControllerFactory(new Callback<Class<?>, Object>() {
@Override
public Object call(Class<?> aClass) {
return context.getBean(aClass);
}
});
return loader.load();
} catch(Exception e) {
e.printStackTrace();
throw new RuntimeException(String.format("Failed to load FXML file '%s'", url));
}
}
}
Поэтому, когда загружается DashboardPresenter, SpringFxmlLoader корректно вводит контроллер с помощью loader.setControllerFactory.
Однако настраиваемый элемент TransactionHistoryPresenter загружается с новым экземпляром, а не из контекста Spring. Он должен использовать собственный FXMLLoader?
Любые идеи о том, как сделать пользовательские элементы управления хорошими с Spring? Я действительно не хочу идти по пути, когда контроллеры/проводники вручную подключают их.