Sada nástrojov JavaFX 2.1 : nie je inicializovaná
Javafx 2 1 Toolkit Not Initialized
dopredu z JavaFX 2.1 : T oolkit nebol inicializovaný
Po prvé, problém
Moja žiadosť je založená na Swingu. Chcem predstaviť JavaFX a nakonfigurovať ho tak, aby vykresľoval scény na sekundárnom displeji. Môžem použiť JFrame na uloženie JFXPanel, ktorý môže obsahovať JFXPanel, ale chcem to urobiť pomocou API JavaFX.
Podtrieda com.sun.glass.ui.Aplikácia a použitie Application.launch (toto) nie je možné, pretože volajúce vlákno bude blokované.
Pri vytváraní inštancie fázy z aplikácie Swing EDT sa zobrazí chyba:
java.lang.IllegalStateException: Toolkit not initialized
problém : Netriviálne aplikácie Swing GUI musia spúšťať komponenty JavaFX. Proces spustenia aplikácie inicializuje grafické používateľské rozhranie po spustení vrstvy závislých služieb.
Riešenie
Podtrieda JavaFX Aplikačná trieda A spustite ho v samostatnom vlákne, napríklad:
public class JavaFXInitializer extends Application { @Override public void start(Stage stage) throws Exception { // JavaFX should be initialized someGlobalVar.setInitialized(true) } }
Bočná poznámka: pretože metóda Application.launch () prijíma jeden Class
parametrov, musia sa na reprezentáciu inicializovaného prostredia JavaFX použiť globálne premenné.
alternatívna metóda: Vytvorte inštanciu JFXPanel vo vlákne dispečera udalostí Swing :
final CountDownLatch latch = new CountDownLatch(1) SwingUtilities.invokeLater(new Runnable() { public void run() { new JFXPanel() // initializes JavaFX environment latch.countDown() } }) latch.await()
Pri použití tejto metódy bude volajúce vlákno čakať, kým sa nenastaví prostredie JavaFX.
Vyberte riešenie, ktoré považujete za vhodné. Vybral som si druhú, pretože nevyžaduje globálnu premennú, ktorá predstavuje inicializáciu prostredia JavaFX, a nestráca vlákno.
(1) Odpoveď 1
Jediným spôsobom, ako používať JavaFX, je podtrieda Aplikácie alebo použitie JFXPanel, práve preto, že majú pripravené env a sadu nástrojov.
Blokovanie vlákien je možné vyriešiť pomocou new Thread(...)
。
Aj keď, ak používate JavaFX na rovnakom VM ako Swing / AWT, odporúčam použiť JFXPanel, viac podrobností nájdete tu: Je v poriadku používať AWT s JavaFx?
(2) Odpoveď 2
Našiel riešenie. Keby som práve vytvoril JFXPanel z Swing EDT pred volaním JavaFX Platform.runLater, bolo by to v poriadku. Neviem, aké spoľahlivé je toto riešenie. Ak je výsledok nestabilný, mohol by som zvoliť JFXPanel a JFrame.
public class BootJavaFX { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JFXPanel() // this will prepare JavaFX toolkit and environment Platform.runLater(new Runnable() { @Override public void run() { StageBuilder.create() .scene(SceneBuilder.create() .width(320) .height(240) .root(LabelBuilder.create() .font(Font.font('Arial', 54)) .text('JavaFX') .build()) .build()) .onCloseRequest(new EventHandler() { @Override public void handle(WindowEvent windowEvent) { System.exit(0) } }) .build() .show() } }) } }) } }
(3) Odpoveď tri
Nasledujúci príkaz som použil pri vytváraní testov jednotiek na testovanie aktualizácií javaFX Tableview.
public class testingTableView { @BeforeClass public static void initToolkit() throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1) SwingUtilities.invokeLater(() -> { new JFXPanel() // initializes JavaFX environment latch.countDown() }) if (!latch.await(5L, TimeUnit.SECONDS)) throw new ExceptionInInitializerError() } @Test public void updateTableView() throws Exception { TableView yourTable = new TableView() .... do your testing stuff } }
Aj keď tento článok nemá nič spoločné s testovaním, pomáha mi dostať sa do práce s jednotkovým testom
- Bez BeforeClass initToolkit bude mať inštancia TableView v unittest za následok chýbajúcu správu sady nástrojov.
(4) Odpoveď 4
Súbor nástrojov môžete tiež výslovne inicializovať volaním: com.sun.javafx.application.PlatformImpl#startup(Runnable)
Trochu hackované, vďaka * impl, ale ak nechcete používať Application
alebo JXFPanel
Užitočné z nejakého dôvodu.
Od tento článok Znovu zverejnite sami seba
(5) Odpoveď päť
Skontroloval som zdrojový kód, aby som ho inicializoval
com.sun.javafx.application.PlatformImpl.startup(()->{})
A ukončite to
com.sun.javafx.application.PlatformImpl.exit()