Одна из наиболее распространенных проблем, возникающих при разработке настольного приложения с помощью JavaFX, заключается в следующем: “Как я могу передать этот пользовательский ввод со сцены От А до сцены Б?”, хотя вы всегда можете положиться на текстовые файлы или даже базы данных, это может быть не самый подходящий подход.
Цель этого урока состоит в том, чтобы научить вас трем различным способам передачи информации из одной сцены в другую. Прежде чем мы углубимся в это, давайте сначала сделаем несколько предположений:
- У нас есть приложение JavaFX с двумя fxml файлами, Сценами |/и Сцена , каждый со своим собственным контроллером, и мы хотим передать данные из пункта А в пункт Б.
- У нас есть класс, который инкапсулирует нужную нам информацию. Ради этого поста предположим, что этот класс определяется следующим образом:
- У нас есть метод с именем
отправка данныхв Контроллере сцены , где мы собираем информацию. Этот метод вызывается при событииmouseClicked - У нас есть метод с именем
получение данныхв Контроллере сцены , где мы заполняем экземпляр класса пользователя информацией, которую мы получаем. Этот метод вызывается при событииmouseClicked
Вот и все 👍 ! Теперь об этих методах…
Первый метод: Использование функции UserData
В JavaFX все классы, которые наследуются от класса Узел имеет следующие методы: setUserData(объект) и getUserData() . Согласно официальной документации, эти методы позволяют нам присоединять произвольный объект к узлу для последующего использования. Я думаю, вы можете видеть, насколько это мощно! Хотя мы можем использовать для этой цели любой узел, я рекомендую вам использовать сам этап , так как он одинаков независимо от сцены.
Чтобы использовать этот метод, в функции sendData выполните следующие действия:
- Сохраните информацию в экземпляре класса пользователя
- Захватите узел, представляющий кнопку, из объекта
событие - Получите экземпляр этапа из узла и закройте его
- Загрузите сцену через класс
FXMLLoader - Передайте информацию на сцену с помощью функции
setUserData - Создайте новую сцену и передайте его на сцену
- Сделайте сцену снова видимой
Функция sendData должна выглядеть примерно так:
В функции receiveData единственное, что нам нужно сделать, это:
- Получите экземпляр стадии , как и раньше
- Восстановите объект с помощью функции
getUserData - Используйте информацию по своему усмотрению
Следовательно, функция receiveData должна выглядеть примерно так:
И вот так нам удалось передать информацию между двумя сценами, “Браво”!. Этот подход очень полезен, когда нам нужен быстрый способ передачи данных туда и обратно но что, если нам нужно передать более одного объекта? Мы увидим, как преодолеть это в следующем разделе.
Второй способ: Ручная настройка контроллеров
Обычно, когда мы создаем наши xml файлы, IDE автоматически создает для них контроллер и связывает их вместе, используя следующее свойство в корневом теге файла fxml :
fx:controller=".Controller"
Кроме того, это также создает новый экземпляр класса контроллера, но если мы хотим передать информацию в поле, хранящееся в контроллере, как в обычном классе, мы должны создать экземпляр вручную.
Чтобы использовать этот метод, нам необходимо выполнить следующие действия:
- Удалите свойство, которое мы видели ранее, из
Scene.xmlфайл - В Контроллере сцены создайте новый атрибут типа user вместе с его
наборомиполучитьфункцию
Вернитесь в функцию sendData :
- Выполните первые три шага, которые мы видели в предыдущем разделе
- Создайте объект
FXMLLoaderи сохраните в нем результат выполнения инструкцииFXMLLoader.load(...) - Создайте новый экземпляр класса Контроллер сцены и передайте ему информацию, используя метод
setвы создали - Используйте метод
setControllerв созданном вами объектеFXMLLoaderи передайте ему экземпляр контроллера - Используйте метод
loadи сохраните его результат вкорневомобъекте, остальное такое же, как и раньше
Функция sendData должна выглядеть примерно так:
Теперь в функции receiveData вы можете отобразить информацию, хранящуюся в поле пользователя, следующим образом:
Этот метод, безусловно, сложнее предыдущего, но теперь вы можете передавать между двумя сценами столько объектов, сколько захотите.
Третий метод: Использование одноэлементного класса
До сих пор мы полагались на контроллеры для передачи информации, но если мы действительно хотим имитировать бизнес-логику, которую мы бы сделали, если бы, например, использовали базу данных, мы можем создать третий класс, из которого два контроллера могут получить доступ. Для этого контроллеры должны совместно использовать один и тот же экземпляр нового класса, и мы можем сделать это с помощью шаблона Singleton .
Существует несколько способов реализации этого шаблона, но самый простой из них заключается в следующем:
- Создайте класс и сделайте его конструктор закрытым, так что новые экземпляры не могут быть созданы
- Создайте константу того же типа, что и класс, и инициализируйте ее
- Создайте общедоступную статическую функцию для извлечения указанной константы
В дополнение к этим шагам вам также необходимо создать поле интересующего вас типа класса, в данном случае user, вместе с его набором и получить функции. Ради этого урока, допустим, мы создадим класс с именем User Holder и выполним следующие действия, это будет результатом:
Вернитесь в функцию sendData :
- Выполните первые 4 шага первого раздела
- Захватите статический экземпляр класса User Holder
- Передайте информацию с помощью функции
setвы создали - В остальном все так же, как и раньше
И, наконец, в функции receiveData вам просто нужно восстановить объект из статического экземпляра, вот так:
И всего за несколько шагов нам удалось обмениваться информацией между сценами с помощью одноэлементного класса. Этот подход особенно полезен при выполнении конфигурации просмотра, вы можете сохранить в одноэлементном классе предпочтения пользователя и легко восстановить их в любом месте вашей программы.
Заключительные мысли
В этом посте мы узнали, как передавать информацию из сцены A к a сцене B тремя различными способами, и мы увидели, как мы будем реализовывать это в нашем коде, а также в некоторых случаях использования, когда они могут вам понадобиться. Я надеюсь, что вы нашли это полезным и хотите поблагодарить вас за потраченное время.
До следующего раза 👋 !
Оригинал: “https://dev.to/devtony101/javafx-3-ways-of-passing-information-between-scenes-1bm8”