Скрыть реализацию Javafx от пользователя - PullRequest
2 голосов
/ 10 июня 2019

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

public void createWindow() {
    Fx window = new Fx();
    window.launchWindow();
}

public static class Fx extends Application {
    private void launchWindow() {
        launch();
    }

    public void start(Stage stage) {
        //javafx code
    }
}

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

Можно ли сделать это частным или сделать какой-то другой обходной путь? Или есть другой способ сделать это?

1 Ответ

7 голосов
/ 10 июня 2019

Использование Application.launch - не единственный способ запустить среду выполнения JavaFX, это просто стандартная и наиболее используемая опция.Другой вариант - использовать Platform.startup(Runnable) (JavaFX 9+).Этот метод запустит среду выполнения JavaFX и вызовет указанный Runnable в потоке приложений JavaFX .

Platform.startup(() -> {
    Stage stage = new Stage();
    stage.setScene(/* your built scene */);
    stage.show();
});

При этой настройке необходимо помнить о некоторых важных вещах:

  1. Среда выполнения JavaFX может быть запущена только один раз для экземпляра JVM;вызов startup во второй раз приведет к IllegalStateException.Если ваш метод может быть вызван более одного раза, вам нужно будет использовать Platform.runLater(Runnable) для второго и последующих вызовов.

  2. После закрытия последнего Stage среда выполнения JavaFX по умолчанию завершится.Как только это произойдет, вы не сможете запустить его снова, пока не перезапустите всю JVM.Чтобы этого не произошло, используйте Platform.setImplicitExit(false).Теперь вы будете нести ответственность за остановку среды выполнения JavaFX с помощью Platform.exit().

  3. Использование startup обходит обычный жизненный цикл JavaFX.Другими словами, экземпляр подкласса Application не будет создан, а методы init(), start(Stage) и stop() не будут вызваны.

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


Если вы используете Java 9+, тогда другой(или хотя бы бесплатный) вариант - использовать модули.Поместите свой класс Application в пакет, который экспортируется только в модуль javafx.graphics.Это предотвратит доступ других модулей к вашему классу Application, даже если он общедоступный.

module app {
    requires javafx.graphics;
    exports com.example to javafx.graphics;
}

Примечание. Это не мешает пользователям использовать classpath или --add-exports, но этобудет "использовать вашу библиотеку неправильно", что означает, что поведение не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...