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()