Могу ли я автоматически генерировать классы контроллеров из FXML?

Как я понимаю, при использовании FXML для описания сцены Java FX класс контроллера записывается вручную, и его переменные-члены и методы могут быть отнесены к файлу .fxml. При загрузке сцены с помощью FXMLLoader переменные-члены устанавливаются в соответствующие элементы сцены, и методы автоматически подключаются к соответствующим событиям. Это работает, но очень громоздко, поскольку изменения должны выполняться в двух местах, и любые ошибки будут отображаться только во время выполнения.

Я видел другие интерфейсы графического интерфейса, которые позволяют вместо этого генерировать контроллер из описания сцены как абстрактного класса, который необходимо реализовать для доступа к элементам сцены и обработки событий. Пример того, что я имею в виду:

Я бы создал следующий .fxml файл (например, с помощью JavaFX Scene Builder):

<AnchorPane ... >
  <children>
     <Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
  </children>
</AnchorPane>

Где-то в моем процессе сборки будет создан следующий файл .java (например, с помощью плагина Maven):

abstract class TestController {
    protected final Parent root;
    protected final Button button;

    {
        // Load test.fxml file
        // Assign scene elements to root and button
        // Attach event handler to the button that calls buttonClicked()
    }

    protected abstract void buttonClicked(ActionEvent event);
}

Я мог бы, возможно, несколько раз создать конкретную реализацию этого контроллера:

final class TestControllerImpl extends TestController {
    TestControllerImpl(String buttonLabel) {
        button.setText(buttonLabel);
    }

    @Override
    protected void buttonClicked(ActionEvent event) {
        button.setText("I've been clicked! What a great day!");
    }
}

Есть ли проект с целью сделать это? Или существует проблема с этим подходом, применяемым к FXML?

Я вижу следующие преимущества этого подхода:

  • Автоматически генерируются объявления переменных-членов и методов для контроллера.
  • Все переменные-члены являются окончательными и защищены вместо нефинальных и общедоступных или аннотированных.
  • То же самое для методов, они защищены, а не публичные или аннотированные.
  • Не внедряя метод или не указывая его имя, это приведет к ошибке компилятора.
  • Программная настройка сцены может быть выполнена в конструкторе вместо метода initialize(), потому что конструктор будет запускаться после загрузки сцены и элементов, назначенных переменным-членам.

Ответ 1

Я ничего не знаю, что делает именно то, что вы предлагаете в своем вопросе.

Вероятно, этот ответ, вероятно, закончится довольно устаревшим с течением времени.

Альтернативные технологии

JRuby достигает большинства ваших намеченных преимуществ с использованием немного другого подхода - он использует магию динамического программирования jRuby для автоматического создания членов класса Ruby из FXML динамически выполняется.

Том Шиндл написал инструмент, который генерирует Java-код из FXML. Из подходов, перечисленных в этом ответе, инструмент Tom кажется ближе всего к вашему вопросу.

Скелеты SceneBuilder

Подобный генератор кода Java из FXML доступен в функции SceneBuilder View | Show Sample Controller Skeleton, описанной в этом сообщении . Когда я использую SceneBuilder, я все время использую эту функцию и стараюсь, чтобы мои контроллеры действительно светились, поэтому они почти полностью сгенерированы с помощью функции скелета SceneBuilder.

Это немного раздражает, потому что он не обеспечивает четкое разделение сгенерированного кода от написанного вручную кода, поэтому вам нужно быть осторожным, когда вы делаете обновления для FXML и хотите сгенерировать новый скелет, скопировать и вставить его над части вашего существующего контроллера (плюс это небольшая ошибка, подверженная ручному управлению, которая занимает немного времени разработчика).

Исходный код для SceneBuilder доступен, если вы хотите увидеть, как он работает.

Потенциальные плагины для сборки инструментов

Такая функция генерации кода может сделать достойное дополнение к некоторым существующим средствам сборки в экосистеме JavaFX, таким как плагин JavaFX Maven или JavaFX Gradle плагин (или отдельный плагин в его собственном праве).

Будущее развитие

Я считаю, что Oracle также работает над расширением функциональности для FXML для будущей версии JavaFX (post Java 8), которая компилирует FXML непосредственно в байт-код Java (файлы классов), минуя шаг исходного кода Java. Этот вид функции, вероятно, достигнет большинства ваших намеченных преимуществ.

Ответ 2

Теперь это поддерживается в SceneBuilder, NetBeans и в Eclipse. Обратите внимание, что это работает из коробки в NetBeans и SceneBuilder, но в Eclipse вам сначала нужен плагин e (fx) для клипов.

SceneBuilder: Открыв файл FXML в редакторе, войдите в меню, чтобы выбрать "Просмотр" и "Показать скелет контрольного образца".

Eclipse: Откройте файл fxml, чтобы содержимое отображалось в панели редактирования кода (вы должны увидеть fxml как обычный текст xml с подсветкой синтаксиса внутри Eclipse, визуально не визуализироваться в SceneBuilder). Щелкните правой кнопкой мыши код в Eclipse и выберите "Код", а затем "Сгенерировать контроллер".

NetBeans: В NetBeans это еще проще, щелкните правой кнопкой мыши файл fxml в проводнике проекта и выберите "Сделать контроллер".

Ответ 3

Это возможно при версии NetBeans версии 8.

Откройте FXML, перейдите в "Источник" и нажмите "Создать контроллер".

Изменить: теперь это можно сделать в любой среде IDE, для Eclipse необходим плагин.

Ответ 4

Как я знаю, в netbeans существуют два вида решений.

Во-первых, внутренняя функция netbeans "Make Controller", которую вы можете увидеть, щелкнув правой кнопкой мыши на документе fxml. он будет генерировать класс контроллера, который будет работать с FXMLLoader. Имя файла java контроллера должно быть указано в документе fxml. (левая панель → Контроллер → Класс контроллера)

Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

Во-вторых, плагин netbeans "Конвертер FXML 2 JAVA", который вы можете установить из меню (Tool → Plugin → Available Plugin → FXML 2 JAVA Converter). и вы можете увидеть пункт меню "Создать абстрактный класс", щелкнув правой кнопкой мыши на документе fxml. Он будет генерировать исходный код из документа fxml, и вы можете использовать его как абстрактный класс, не используя FXMLLoader, как обычный проект JavaFX, а не проект JavaFXML.

Ответ 5

@Feuermurmel
нет нет способов генерировать автоматически класс контроллера для файла particula.fxml.
вы должны определить динамически объявить переменную и метод с помощью anotation @fxml и установить (bind) в конструкторе scence.

Ответ 6

Теперь вы можете легко сделать это с помощью Eclipse. Просто сделайте эти простые шаги:

  1. Перейдите к вашему файлу fxml, для которого вы хотите создать контроллер
  2. Щелкните правой кнопкой мыши и выберите источник
  3. Нажмите Создать контроллер

Нажмите здесь, чтобы увидеть картину, как это сделать.

Ответ 7

Если вы используете IntelliJ ide, вам, возможно, придется попробовать плагин FXML Helper.

Сначала установите плагин из файла | Настройки... | Плагины. После установки перезапустите ide, теперь щелкните правой кнопкой мыши на документе .fxml и выберите меню FXML Helper. Все это.