Почему при импорте javafx.scene.control.Button происходит сбой, когда Toolkit не инициализирован?

Я пробую базовые вещи с JavaFX с Clojure, на 64-разрядной версии Java8 (1.8.0_05-b13) в Windows 7.

В моем импорте (будь то в файле .clj или в REPL) я могу (import 'javafx.scene.control.ButtonBuilder) (и другие компоновщики), но я не могу (import 'javafx.scene.control.Button) или любой другой окончательный виджет из javax.scene.control.

Если я попытаюсь импортировать javafx.scene.control.Button или другой виджет, я получу ошибку Toolkit Not Initialized. То же самое с попыткой создать кнопку с помощью ButtonBuilder, хотя сам класс ButtonBuilder работает нормально, и кажется, что я вполне могу импортировать другие вещи из иерархии javafx.

Чтобы заставить его работать, я должен принудительно инициализировать инструментарий, как показано здесь, что, я думаю, оставляет где-то панель Orphan, которая кажется грязной: https://gist.github.com/zilti/6286307

(ns hello.core
  (:import (javafx.event ActionEvent EventHandler)
           (javafx.scene Scene SceneBuilder)
           (javafx.scene.layout VBox VBoxBuilder)
           ;;(javafx.scene.control Button) -- MUST COMMENT THIS OUT OR FAIL
           (javafx.scene.control ButtonBuilder)
           (javafx.stage Stage StageBuilder)))

(defonce force-toolkit-init (javafx.embed.swing.JFXPanel.))

Это было не так с Java 7 и javafxrt.jar. Единственное обсуждение этого, которое я нашел (на SO), показывает, что это необходимо для взаимодействия Swing, которое я не использую.

Может кто-нибудь объяснить, почему это требуется сейчас с Java8 и почему это требуется только для конечных виджетов, таких как Button?

Это похоже на волшебное обходное решение. Есть ли какое-то реальное решение?


person Sonicsmooth    schedule 04.05.2014    source источник


Ответы (1)


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

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

Вызов JFXPanel также выполнит инициализацию, но это своего рода взлом (если вы действительно не используете свинг и FX в одном приложении).

person Sergey Grinev    schedule 06.05.2014
comment
Таким образом, тот факт, что другие вещи работают, например, открытие главного окна, в основном является неопределенным, но все же полезным поведением? Раньше я использовал метод :gen-class для получения от Application, но я хотел посмотреть, смогу ли я получить контроль REPL над графическим интерфейсом. Пока я могу создавать виджеты (после инициализации), но когда я закрываю окно, я не могу запустить его снова. Это на самом деле главная цель, чтобы сократить время запуска до незначительного времени. - person Sonicsmooth; 07.05.2014
comment
да, и ваш первоначальный подход был более правильным. Про невозможность снова запустить windows лучше задать в другом вопросе с более подробной информацией. - person Sergey Grinev; 07.05.2014