Мое приложение основано на Swing. Я хотел бы представить JavaFX и настроить его для рендеринга сцены на вторичном дисплее. Я мог бы использовать JFrame для хранения JFXPanel, который мог бы содержать JFXPanel, но я хотел бы достичь этого с помощью API JavaFX.
Подклассификация com.sun.glass.ui.Приложение и использование Application.launch(это) не является опцией, потому что вызывающий поток будет заблокирован.
При создании экземпляра Stage из Swing EDT появляется ошибка:
java.lang.IllegalStateException: Toolkit not initialized
Любые указатели?
EDIT: Выводы
Проблема: нетривиальное приложение GUI Swing должно запускать компоненты JavaFX. Процесс запуска приложения инициализирует графический интерфейс после запуска зависимого служебного уровня.
Решения
Подкласс JavaFX Application class и запустите его в отдельном потоке, например:
public class JavaFXInitializer extends Application {
@Override
public void start(Stage stage) throws Exception {
// JavaFX should be initialized
someGlobalVar.setInitialized(true);
}
}
Sidenote: поскольку метод Application.launch() принимает в качестве аргумента Class<? extends Application>
, необходимо использовать глобальную переменную для сигнатуры среды JavaFX.
Альтернативный подход: создать экземпляр JFXPanel в потоке диспетчера событий Swing:
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JFXPanel(); // initializes JavaFX environment
latch.countDown();
}
});
latch.await();
Используя этот подход, вызывающий поток будет ждать настройки среды JavaFX.
Выберите любое решение, которое вам подходит. Я пошел со вторым, потому что ему не нужна глобальная переменная, чтобы сигнализировать инициализацию среды JavaFX, а также не тратить поток.