У меня есть метод FXML onExitButtonClick в MenuController.java, как я могу получить доступ к тому же методу FXML в GameOverController.java? Одна из кнопок выхода находится в сцене меню, а другая - в сцене окончания игры.

MenuController.java

@FXML
private void onExitButtonClick() {
    System.out.println("Goodbye " + System.getProperty("user.name"));
    System.exit(0);
}

GameOverController.java

@FXML
private void onExitButtonClick() {
    System.out.println("Goodbye " + System.getProperty("user.name"));
    System.exit(0);
}

Есть ли способ уменьшить избыточность кода?

0
Cheang Wai Bin 27 Ноя 2021 в 09:39
Проведите небольшое исследование в области Java.
 – 
Zephyr
27 Ноя 2021 в 09:49

1 ответ

Лучший ответ

Конкретный ответ на заголовок вопроса

Как получить доступ к методу FXML с другого контроллера

Не надо.

Контроллерам не нужно вызывать методы друг у друга, за исключением конкретного случая:

Даже в этом случае это не лучшая практика для большинства приложений.

Лучше всего использовать классы общих моделей и логику обслуживания вне контроллеров с помощью mvc. Логика контроллера должна быть ограничена управлением представлением и связыванием модели представления с помощью слушателей и привязки к объектной модели.

Для общих компонентов пользовательского интерфейса создайте собственные классы виджетов и повторно используйте их. См., Например, учебник Oracle:

Использование fxml в настраиваемых элементах управления необязательно, но концепция аналогична руководству. Вы можете написать свой собственный элемент управления на простом языке Java. Также обычно достаточно, чтобы он расширял панель, а не Control, так как это проще.

В общем случае используйте mvc

Если вы хотите провести рефакторинг, разумным решением будет не выполнять логику приложения в контроллерах, а вместо этого иметь общий уровень службы уровня домена, отдельный от пользовательского интерфейса и контроллеров, который работает с общей объектной моделью.

Для получения информации см .:

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

Конкретный случай завершения работы приложения: статический метод приложения

Ваш конкретный случай выхода из приложения - особый, который не применим в большинстве других ситуаций. Особенностью является то, что выход - это действительно функция уровня приложения, и уже существует определенный класс, который обрабатывает жизненный цикл приложения. Это будет ваш класс, являющийся подклассом Application. Таким образом, имеет смысл только то, что код для обработки выхода будет идти туда.

Чтобы лучше понять жизненный цикл приложения, я настоятельно рекомендую вам перечитать JavaFX Приложение javadoc.

В JVM разрешен только один экземпляр приложения, поэтому можно получить доступ к этому экземпляру из любого места вашего приложения с помощью статических методов.

Итак, обладая этим знанием, мы можем провести рефакторинг ваших вызовов. В любом контроллере или в любом другом месте, где вы хотите завершить работу приложения, напишите:

@FXML
private void onExitButtonClick() {
    MyApplication.exit();
}

И в вашем классе приложения определите статический метод:

public static void exit() {
    System.out.println("Goodbye " + System.getProperty("user.name"));
    Platform.exit();
}

Обратите внимание, что выполняется вызов для выхода из платформы, а не из системы, потому что это рекомендуемый способ завершения работы приложения в жизненном цикле приложения JavaFX. Вы можете передать параметр для вызова выхода, если хотите предоставить некоторый контекст для выхода (например, сообщение о причине выхода).

Этот метод вызова статической функции в приложении также может использоваться для другой общей логики.

За пределами небольших тривиальных приложений я бы рекомендовал этот подход только для логики, непосредственно связанной с жизненным циклом приложения.

Такие методы, как mvc, общие объектные модели с привязываемыми свойствами и внедрение зависимостей, рекомендуются для общей логики в более крупных приложениях.

Конкретный случай завершения работы приложения: интеграция жизненного цикла приложения

Поскольку это особый случай работы с жизненным циклом приложения, вы можете более тесно интегрироваться с ним и полностью удалить дополнительный статический метод. Если вы это сделаете, вы получите этот код, чтобы просто вызывать Platform.exit () всякий раз, когда вы хотите выйти:

@FXML
private void onExitButtonClick() {
    Platform.exit();
}

И в вашем коде класса приложения JavaFX:

@Override
public void stop() {
    System.out.println("Goodbye " + System.getProperty("user.name"));
}

Это работает, потому что метод stop () - это обратный вызов, вызываемый при выходе из платформы.

Кстати, именно поэтому вы должны вызывать Platform.exit, а не System.exit. Если вы выйдете из системы напрямую, это приведет к короткому замыканию логики выключения платформы, и логика остановки не будет вызвана.

1
jewelsea 27 Ноя 2021 в 11:01