Под initialize()
Я предполагаю, что вы имеете в виду метод initialize()
в контроллере, а не метод init()
в вашем классе Application
(дайте мне знать, если я ошибаюсь).Это можно сделать двумя способами:
Не использовать fx:controller
в файле FXML.Скорее создайте свой собственный экземпляр и настройте его.Затем вы звоните loader.setController(controller)
до и звоните load()
.
Используйте фабрику контроллера через setControllerFactory(Callback)
.Здесь вы все равно используете fx:controller
и можете фактически передать this
в конструктор класса вашего контроллера.
Пример для опции # 2:
FXMLLoader loader = new FXMLLoader();
loader.setLocation(/* your location */);
loader.setControllerFactory(clazz -> {
if (YourController.class.equals(clazz)) {
return new YourController(this);
} else {
try {
return clazz.getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex); // bail
}
}
});
Parent root = loader.load();
Возможно, вы сможете удалить проверку if
, а также все, что находится внутри else
, если вы знаете , что фабрикой контроллеров будет создан только YourController
.
Изменить: Альтернативный пример для опции # 2
Это было упомянуто в комментариях Фабиана.Я публикую его здесь, потому что читать код в ответе намного проще, чем в комментарии.
loader.setControllerFactory(clazz -> {
Object controller;
try {
controller = clazz.getConstructor().newInstance();
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
if (controller instanceof BaseController) {
((BaseController) controller).setMainApp(this);
}
return controller;
});
Где BaseController
может быть интерфейсом или абстрактным классом.Это позволяет вам избегать проверки для каждого типа, который требует специальной обработки.
И, опять же, упомянутое fabian, вы можете пойти еще дальше, внедрив инфраструктуру внедрения зависимостей, такую как AfterburnerFX или CDI (внедрение контекста и зависимости).).