Как я могу передать параметры во вторичное окно в javafx? Есть ли способ связи с соответствующим контроллером?
Например: пользователь выбирает клиента из списка, TableView
и открывается новое окно с информацией о клиенте.
Stage newStage = new Stage();
try
{
AnchorPane page = (AnchorPane) FXMLLoader.load(HectorGestion.class.getResource(fxmlResource));
Scene scene = new Scene(page);
newStage.setScene(scene);
newStage.setTitle(windowTitle);
newStage.setResizable(isResizable);
if(showRightAway)
{
newStage.show();
}
}
newStage
будет новое окно. Проблема в том, что я не могу найти способ сообщить контроллеру, где искать информацию о клиенте (передавая id в качестве параметра).
Любые идеи?
Ответы:
Рекомендуемый подход
Этот ответ перечисляет различные механизмы для передачи параметров в контроллеры FXML.
Для небольших приложений я настоятельно рекомендую передавать параметры непосредственно от вызывающей стороны к контроллеру - это просто, просто и не требует дополнительных платформ.
Для более крупных и сложных приложений было бы целесообразно выяснить, хотите ли вы использовать в своем приложении механизмы Dependency Injection или Event Bus .
Передача параметров напрямую от вызывающего к контроллеру
Передайте пользовательские данные в контроллер FXML, извлекая контроллер из экземпляра загрузчика FXML и вызывая метод на контроллере, чтобы инициализировать его необходимыми значениями данных.
Что-то вроде следующего кода:
Новый FXMLLoader строится , как показано в примере кода , т.е.
new FXMLLoader(location)
. Расположение является URL-адресом, и вы можете создать такой URL-адрес из ресурса FXML:Будьте осторожны, НЕ используйте функцию статической загрузки на FXMLLoader, иначе вы не сможете получить свой контроллер от экземпляра загрузчика.
Сами экземпляры FXMLLoader никогда ничего не знают об объектах домена. Вы непосредственно не передаете специфичные для приложения доменные объекты в конструктор FXMLLoader, вместо этого вы:
Этот блог (другой автор) предоставляет альтернативный, но похожий пример .
Настройка контроллера на FXMLLoader
Вы можете создать новый контроллер в коде, передавая любые параметры из вызывающей программы в конструктор контроллера. Создав контроллер, вы можете установить его на экземпляр 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 использует Jav6 javax.inject для выполнения внедрения зависимостей.
Используйте шину событий
Грег Браун (Greg Brown), создатель и разработчик оригинальной спецификации FXML, часто предлагает рассмотреть возможность использования шины событий, такой как Guava EventBus , для связи между экземплярами контроллера FXML и другой логикой приложения.
Последующие вопросы и ответы
Это функциональное решение проблемы. Этап возвращается из
showCustomerDialog
функции, так что ссылка на него может быть сохранена внешним классом, который может захотеть что-то сделать, например скрыть этап на основе нажатия кнопки в главном окне, в более позднее время. Альтернативное объектно-ориентированное решение может инкапсулировать функциональность и ссылку на стадию в объекте CustomerDialog или иметь расширенную стадию CustomerDialog. Полный пример объектно-ориентированного интерфейса с настраиваемым диалоговым окном, инкапсулирующим данные FXML, контроллера и модели, выходит за рамки этого ответа, но может стать достойной записью в блоге для любого, кто хочет его создать.Дополнительная информация предоставлена пользователем StackOverflow с именем @dzim
Пример для инъекции зависимостей весенней загрузки
На вопрос, как это сделать «The Spring Boot Way», шла дискуссия о JavaFX 2, на которую я ответил в прикрепленной постоянной ссылке. Этот подход все еще действителен и протестирован в марте 2016 года на Spring Boot v1.3.3.RELEASE: https://stackoverflow.com/a/36310391/1281217
Иногда вы можете захотеть передать результаты обратно вызывающей стороне, и в этом случае вы можете проверить ответ на соответствующий вопрос:
источник
В этом примере мы будем использовать 5 файлов:
Все файлы перечислены полностью в нижней части этого поста.
Цель: продемонстрировать передачу значений из
Controller1
вController2
и наоборот.Ход программы:
TextField
, aButton
и aLabel
. КогдаButton
нажата кнопка, загружается и отображается второе окно, включая текст, введенный вTextField
.TextField
, aButton
и aLabel
. НаLabel
экране отобразится текст, введенный вTextField
первой сцене.TextField
и щелчка по нейButton
, первая сценаLabel
обновляется, чтобы показать введенный текст.Это очень простая демонстрация, которая, безусловно, может означать некоторое улучшение, но она должна сделать концепцию очень ясной.
Сам код также прокомментирован с некоторыми деталями того, что происходит и как.
Main.java:
Controller1.java:
Controller2.java:
Layout1.fxml:
Layout2.fxml:
источник
loader.setController(this)
и добавление контроллера в файл FXML приводит к сбою приложенияloader.getController()
Класс javafx.scene.Node содержит пару методов setUserData (Object) и Object getUserData ().
Который вы могли бы использовать, чтобы добавить свою информацию в узел.
Таким образом, вы можете вызвать page.setUserData (info);
И контроллер может проверить, установлена ли информация. Кроме того, вы можете использовать ObjectProperty для обратной передачи данных, если это необходимо.
Ознакомьтесь с документацией здесь: http://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html Перед фразой «В первой версии handleButtonAction () помечен как @FXML чтобы позволить разметке, определенной в документе контроллера, вызывать ее. Во втором примере поле кнопки аннотировано, чтобы позволить загрузчику установить его значение. Метод initialize () также аннотирован. "
Итак, вам нужно связать контроллер с узлом и установить пользовательские данные для узла.
источник
Вот пример для передачи параметров в документ fxml через пространство имен.
Определите значение
External Text
для переменной пространства именlabelText
:источник
FXMLLoader.CONTROLLER_KEYWORD
,FXMLLoader.LOCATION_KEY
,FXMLLoader.RESOURCES_KEY
и любая строка , которая используется в качестве значения дляfx:id
атрибута.Это работает ..
Помните, что в первый раз, когда вы печатаете передаваемое значение, вы получаете нулевое значение. Вы можете использовать его после загрузки ваших окон, то же самое для всего, что вы хотите закодировать для любого другого компонента.
источник
Вы должны создать один класс контекста.
Вы должны просто установить экземпляр контроллера в инициализации, используя
и вы можете использовать его из всего приложения, просто используя
Теперь вы можете передать параметр на любой контроллер из всего приложения.
источник
Да, ты можешь.
Вам нужно добавить в первый контроллер:
Затем во втором объявите клиента, а затем в нижней части вашего контроллера:
источник
Вот пример использования контроллера, введенного Guice.
Вот конкретная реализация загрузчика:
Обратите внимание, что этот пример загружает представление в центр BoarderPane, который является корнем сцены в рабочей области. Это не относится к примеру (подробности реализации моего конкретного варианта использования), но решил оставить его, так как некоторые могут найти его полезным.
источник
Вы можете решить использовать общедоступный список наблюдаемых для хранения общедоступных данных или просто создать метод общедоступного сеттера для хранения данных и извлечения из соответствующего контроллера.
источник
Зачем отвечать на 6-летний вопрос?
Одна из самых фундаментальных концепций работы с любым языком программирования - как перемещаться от одного (окна, формы или страницы) к другому. Также, выполняя эту навигацию, разработчик часто хочет передавать данные из одного (окна, формы или страницы) и отображать или использовать переданные данные.
В то время как большинство ответов здесь дают хорошие и отличные примеры, как этого добиться, мы думали, что мы их подгоним метка, две или три
Мы сказали три, потому что мы будем перемещаться между тремя (окном, формой или страницей) и будем использовать концепцию статических переменных для передачи данных вокруг (окна, формы или страницы).
Мы также включим некоторый код принятия решений, пока мы ориентируемся
Контроллер запуска
Контроллер первой страницы
Контроллер второй страницы
Ниже приведены все файлы FXML
источник