Javafx – class приложения может быть classом controllerа

В настоящее время я преподаю JavaFX, и я взял простую примерную программу, которая жестко закодировала представление и превратила его в тот, который использует FXML (в основном, поэтому я могу использовать SceneBuilder для создания пользовательских интерфейсов). Вместо того, чтобы писать отдельный class controllerа, я использую class приложения (поэтому есть 1 файл Java и 1 файл FXML). Я не использую метод initialize() поскольку это линейный stream (отображение пользовательского интерфейса, заполнение полей, ожидание ввода). Появится всплывающее окно, но затем ошибки приложения исчезнут, так как ни один из элементов управления не сопоставлен с соответствующими переменными (поэтому для @FXML TableView table table равна null ).

Тем не менее, я ввел метод initialize() для отладки, элементы управления инъецируются во время initialize() , а затем возвращаются к нуле при initialize() .

Итак, вопрос в том, реализует ли JavaFX новый экземпляр classа приложения как отдельный class controllerа? Это объясняет, почему переменная выходит за frameworks. Или это что-то еще (например, элементы управления вводятся только при вызове из действий JavaFX)?

Поведение FXMLLoader по FXMLLoader – это создать новый экземпляр classа controllerа и использовать этот экземпляр в качестве controllerа.

В частности, FXMLLoader делает что-то вроде:

  • Прочитайте корневой элемент FXML.
    • Если корневой элемент FXML имеет атрибут fx:controller , тогда
      • Если controller уже существует, генерируйте исключение, в противном случае создайте экземпляр указанного classа 1 и установите его как controller
  • Продолжайте анализ файла FXML. Если элементы имеют атрибут fx:id , а controller существует (любым механизмом), вставьте эти поля в controller. Аналогичным образом регистрируют обработчики событий как вызовы методов в экземпляре controllerа.
  • Вызовите initialize() на controllerе, если controller существует и имеет такой метод.

Итак, вопрос, который вы задали:

Может ли class приложения быть classом controllerа

Да, но это, наверное, ужасная идея. Если вы просто определяете подclass Application как class controllerа с помощью fx:controller , то создается второй экземпляр подclassа Application , в этот второй экземпляр вводятся @FXML -занятые поля, а на этот второй @FXML вызывается метод initialize() пример. Очевидно, что @FXML @FXML никогда не инициализируются в экземпляре, на котором вызывается start(...) , и метод initialize() никогда не вызывается в этом экземпляре.

Вопрос, который вы, вероятно, имели в виду:

Может ли экземпляр classа приложения, созданный при запуске, использоваться в качестве controllerа?

Ответ на это также да, и, помимо очень маленьких демо-программ, которые вы намереваетесь немедленно отбросить, это также, вероятно, очень плохая идея. Вы сделали бы это

 public class MyApp extends Application { @FXML private Node someNode ; public void initialize() { // do something with someNode } @Override public void start(Stage primaryStage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/path/to/fxml/file.fxml")); loader.setController(this); Parent root = loader.load(); primaryStage.setScene(new Scene(root)); primaryStage.show(); } } 

Обратите внимание, что для использования этого кода ваш файл FXML не должен иметь атрибут fx:controller .

Проблема заключается в том, что у вас нет разделения и нет гибкости. (Например, если вы создаете второй экземпляр представления, определенного в вашем файле FXML, вы получите второй экземпляр подclassа Application , который в лучшем случае несовместим (одно приложение с двумя экземплярами Application …).)

Поэтому я бы рекомендовал использовать отдельный class для controllerа в основном в каждом случае. Подclass Application должен содержать минимальный код и должен использоваться только для запуска приложения.

1 Этот шаг на самом деле немного сложнее. Если class указан в атрибуте fx:controller , и controller уже не существует, FXMLLoader проверяет наличие controllerFactory . Если таковой существует, то controller устанавливается как результат передачи указанного Class методу call() метода controllerFactory , в противном случае он создается путем вызова newInstance() в указанном classе (фактически вызывающего его конструктор без аргументов).

Если вы определили свой class приложений как controller в файле FXML, JavaFX, если я правильно помню, создаст новый экземпляр вашего classа приложения и воспользуюсь новым экземпляром в качестве controllerа. Таким образом, ваш существующий class приложения по-прежнему имеет значение null для таблицы.

Однако вы можете определить controller программным способом в своем classе приложения, чтобы использовать свой собственный экземпляр:

 FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("example.fxml")); fxmlLoader.setController(this); Parent root = (Parent)fxmlLoader.load(); 
  • Применение MVC с помощью JavaFx
  • javafx, используя объекты MainController или других controllerов в соответствующем classе controllerа
  • Значение изменения JavaFX ComboBox вызывает IndexOutOfBoundsException
  • Инъекция зависимостей и JavaFX
  • Как ссылаться на файлы javafx fxml в папке ресурса?
  • Воспроизведение видео Youtube с использованием JavaFX
  • Как добавить маркер значения в диаграмму JavaFX?
  • Эффект JavaFX на фоне
  • Производительность WebView в JavaFX
  • Как создать несколько controllerов javafx с разными файлами fxml?
  • Использование шаблона наблюдателя в дизайне GUI JavaFX
  • Interesting Posts

    Если я выполняю обновление до Windows 8, должен ли я иметь установленную предыдущую версию или просто достаточно ключа?

    Не удается удалить раздел в diskpart – недопустимый аргумент?

    Зачем использовать redirect JSF ExceptionHandlerFactory вместо перенаправления ?

    Стоит ли тратить время на обучение Emacs?

    Запись PCM записанных данных в WAV-файл (java android)

    Сравните равенство между двумя объектами в NUnit

    Самый точный способ выполнить комбинированную операцию умножения и деления в 64-битном режиме?

    Созданные iTextSharp PDF-файлы теперь вызывают диалог сохранения в Adobe Reader X

    Javascript regex для проверки адреса IPv4 и IPv6, никаких имен хостов

    Как обрезать ведущие и завершающие пробелы?

    Ssh попытки атаки на OS X 10.10 – должен ли я беспокоиться / отвечать?

    Как установить предыдущую версию Chrome?

    Эффективное умножение векторных матриц 4×4 на SSE: горизонтальное добавление и точечный продукт – в чем смысл?

    Запрос MySQL для выбора результатов с автоматическим приращением в качестве нового столбца, добавленного в результат

    Создание символов 256-цветного и линейного рисования работает в PuTTY

    Давайте будем гением компьютера.