Рекомендований підхід
Ця відповідь перераховує різні механізми передачі параметрів FXML-контролерам.
Для невеликих програм я дуже рекомендую передавати параметри безпосередньо від абонента до контролера - це просто, просто та не вимагає додаткових кадрів.
Для великих, складніших додатків варто вивчити, чи ви хочете використовувати механізми введення залежності або шини подій у вашій програмі.
Передача параметрів безпосередньо від абонента до контролера
Передайте власні дані контролеру FXML, отримавши контролер з екземпляра завантажувача FXML та викликаючи метод на контролері, щоб ініціалізувати його з необхідними значеннями даних.
Щось на зразок наступного коду:
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(
(Pane) loader.load()
)
);
CustomerDialogController controller =
loader.<CustomerDialogController>getController();
controller.initData(customer);
stage.show();
return stage;
}
...
class CustomerDialogController {
@FXML private Label customerName;
void initialize() {}
void initData(Customer customer) {
customerName.setText(customer.getName());
}
}
Створено новий FXMLLoader, як показано у зразковому коді, тобто new FXMLLoader(location)
. Місцезнаходження - це URL-адреса, і ви можете генерувати таку URL-адресу з ресурсу FXML:
new FXMLLoader(getClass().getResource("sample.fxml"));
Будьте обережні НЕ використовуйте функцію статичного навантаження на FXMLLoader, інакше ви не зможете отримати свій контролер з екземпляра завантажувача.
Самі екземпляри FXMLLoader ніколи нічого не знають про об'єкти домену. Ви безпосередньо не передаєте конкретні доменні об’єкти додатку в конструктор FXMLLoader, натомість ви:
- Побудуйте FXMLLoader на основі розмітки fxml у вказаному місці
- Отримайте контролер від екземпляра FXMLLoader.
- Викликати методи на отриманому контролері для надання контролеру посилань на об'єкти домену.
Цей блог (іншого письменника) дає альтернативний, але подібний приклад .
Встановлення контролера на FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
Ви можете сконструювати новий код у коді, передаючи будь-які параметри від свого абонента в конструктор контролера. Після того як ви сконструювали контролер, ви можете встановити його на екземпляр FXMLLoader перед тим, як викликати метод load()
екземпляра .
Щоб встановити контролер на завантажувач (у JavaFX 2.x), ви не можете також визначити fx:controller
атрибут у файлі fxml.
Через обмеження fx:controller
визначення у FXML я особисто вважаю за краще отримувати контролер від FXMLLoader, а не встановлювати контролер у FXMLLoader.
Наявність контролера отримання параметрів із зовнішнього статичного методу
Цей метод є прикладом відповіді Сергія на Javafx 2.0 How-to Application.getParameters () у файлі Controller.java .
Використовуйте ін'єкційну залежність
FXMLLoader підтримує системи ін'єкцій залежностей, такі як Guice, Spring або Java EE CDI, дозволяючи встановити на FXMLLoader спеціальний заводський контролер. Це забезпечує зворотний виклик, який можна використовувати для створення екземпляра контролера із залежними значеннями, введеними відповідною системою введення залежності.
Приклад застосування JavaFX та інженерії залежності контролера від Spring наведено у відповіді на:
По-справжньому приємний, чистий підхід до ін'єкцій залежностей є прикладом системи afterburner.fx із зразком програми air-hacks, яка його використовує. afterburner.fx покладається на JEE6 javax.inject для виконання ін'єкції залежності.
Використовуйте автобус подій
Грег Браун, оригінальний творець специфікації FXML та реалізатор, часто пропонує розглянути можливість використання шини подій, наприклад Guava EventBus , для зв'язку між контролерами FXML, що інстанціюються, та іншою логікою програми.
EventBus - це простий, але потужний API публікації / підписки з анотаціями, який дозволяє POJO спілкуватися між собою в будь-якому місці JVM, не звертаючись один до одного.
Подальші запитання та запитання
на першому методі, чому ви повертаєте етап? Цей метод може бути недійсним, оскільки ви вже даєте команду show (); безпосередньо перед етапом повернення ;. Як планувати використання, повертаючи Етап
Це функціональне рішення проблеми. Етап повертається з showCustomerDialog
функції, так що посилання на нього може зберігатися зовнішнім класом, який, можливо, захоче щось зробити, наприклад приховати етап на основі натискання кнопки в головному вікні, пізніше. Альтернативне, об'єктно-орієнтоване рішення може інкапсулювати функціональність та посилання на етапи всередині об'єкта CustomerDialog або мати етап Extension CustomerDialog. Повний приклад об'єктно-орієнтованого інтерфейсу до спеціального діалогового вікна, що інкапсулює дані FXML, контролера та моделі, виходить за рамки цієї відповіді, але може зробити корисну публікацію в блозі для тих, хто схильний її створити.
Додаткова інформація, надана користувачем StackOverflow на ім'я @dzim
Приклад вприскування залежної залежності завантаження
Питання про те, як це зробити "Весняний завантажувальний шлях", відбулося обговорення JavaFX 2, яке я озвучив у доданій постійній посилання. Підхід досі діє та перевірений у березні 2016 року на Spring Boot v1.3.3.RELEASE:
https://stackoverflow.com/a/36310391/1281217
Іноді, можливо, ви захочете повернути результати тому, хто телефонує, і в цьому випадку ви можете перевірити відповідь на відповідне запитання: