Swing JFrame mit JFXPanel NPE bei dispose()

Hans_G

Mitglied
Von einem Swing JFrame aus soll ein neues JFrame geöffnet werden, in dem ein JFXPanel enthalten ist. Wenn dieses zweite Frame geschlossen wird, tritt eine NullPointerException auf.

Ich habe zur Anschauung einfach das Beispiel von Oracle http://docs.oracle.com/javafx/2/swing/swing-fx-interoperability.htm so erweitert, dass erst ein JFrame mit einem Button erscheint, über den man das JFrame mit dem JFXPanel aus dem Beispiel öffnet:
Java:
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {
    
// Hier meine Erweiterung *****************************
    private static void showStartGUI() {
        JFrame frame = new JFrame("Start");
        JButton showButton = new JButton("Show");
        showButton.addActionListener(e-> initAndShowGUI());
        frame.add(showButton);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
// Ende meiner Erweiterung ****************************

    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Swing and JavaFX");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                initFX(fxPanel);
            }
       });
    }

    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }

    private static Scene createScene() {
        Group  root  =  new  Group();
        Scene  scene  =  new  Scene(root, Color.ALICEBLUE);
        Text  text  =  new  Text();
       
        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Welcome JavaFX!");

        root.getChildren().add(text);

        return (scene);
    }
   
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                showStartGUI(); // ersetzt initAndShowGUI() aus dem Original
            }
        });
    }
}

Beim Schließen des JFrames mit JFXPanel, passiert entweder

1: Eine NullPointerException wird geworfen:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javafx.embed.swing.JFXPanel.getInputMethodRequests(JFXPanel.java:810)
    at sun.awt.im.InputMethodAdapter.haveActiveClient(InputMethodAdapter.java:61)
    at sun.awt.X11InputMethod.deactivate(X11InputMethod.java:377)
    at sun.awt.im.InputContext.deactivateInputMethod(InputContext.java:492)
    at sun.awt.im.InputContext.focusLost(InputContext.java:458)
    at sun.awt.im.InputContext.removeNotify(InputContext.java:627)
    at java.awt.Component.removeNotify(Component.java:7018)
    at java.awt.Container.removeNotify(Container.java:2820)
    at javax.swing.JComponent.removeNotify(JComponent.java:4758)
    at javafx.embed.swing.JFXPanel.removeNotify(JFXPanel.java:829)
    at java.awt.Container.removeNotify(Container.java:2804)
    at javax.swing.JComponent.removeNotify(JComponent.java:4758)
    at java.awt.Container.removeNotify(Container.java:2804)
    at javax.swing.JComponent.removeNotify(JComponent.java:4758)
    at java.awt.Container.removeNotify(Container.java:2804)
    at javax.swing.JComponent.removeNotify(JComponent.java:4758)
    at javax.swing.JRootPane.removeNotify(JRootPane.java:765)
    at java.awt.Container.removeNotify(Container.java:2804)
    at java.awt.Window.removeNotify(Window.java:782)
    at java.awt.Frame.removeNotify(Frame.java:1041)
    at java.awt.Window$1DisposeAction.run(Window.java:1194)
    at java.awt.Window.doDispose(Window.java:1210)
    at java.awt.Window.dispose(Window.java:1151)
    at javax.swing.JFrame.processWindowEvent(JFrame.java:313)
    at java.awt.Window.processEvent(Window.java:2017)
    at java.awt.Component.dispatchEventImpl(Component.java:4891)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Window.dispatchEventImpl(Window.java:2750)
    at java.awt.Component.dispatchEvent(Component.java:4713)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Die Anwendung läuft aber normal weiter und man kann den JFrame auch wieder per Buttonclick öffnen.

2: Es wird keine NullPointerException geworfen, dafür erscheint beim erneuten Klick auf den Button das JFrame als leeres Fenster (ohne JFXPanel-Inhalt).

Was ist hier los?
 

Hans_G

Mitglied
Danke für den Hinweis. Ich dachte schon, das Problem liegt auf meiner Seite. JFXPanel scheint also buggy zu sein. Ich weiche dann mal lieber auf eine andere Bibliothek für das Zeichnen von Diagrammen aus. Dafür wollte ich die Java-FX-Integration nämlich verwenden.
 

dzim

Top Contributor
Ich weiss nicht, ob das per se ein Problem ist. Es scheint ja nur in gewissen Situationen zu sein... Da ich aber kein Swing-Entwickler bin und mit somit auch noch nie mit der Swing-Interopt auseinandergesetzt habe, kann ich nur mutmassen.
Ich denke mal schon, dass du dich um die unterschiedlichen UI-Threads gekümmert haben wirst, oder? Denn Swing und JavaFX haben jeweils eigene UI-Threads (im Gegensatz zu SWT und JavaFX, die auf dem selben UI-Thread arbeiten, was es deutlich einfacher macht).
 

Hans_G

Mitglied
Nun, ich habe es mit den Threads eben so gemacht, wie es im Code oben zu sehen ist.

Ich finde auch, dass das Anwendungsszenario zum Code - über ein Standard Swing-Frame ein Swing-Frame mit JFXPanel öffnen, es wieder schließen und ggf. erneut öffnen - gewöhnlich genug ist, dass es funktionieren sollte. Gleichermaßen betrachte ich das Code-Beispiel oben als simpel genug, dass es entweder auf Anhieb funktioniert oder ein möglicher Fehler meinerseits offensichtlich wird.

Das mögliche Workaround ist mir zu unsicher, da es als Java-Versions- und evtl. OS-abhängig gesehen wird. Ferner unterscheidet sich jenes Szenario leicht von meinem, sodass ich die Übertragbarkeit nicht direkt sehe. Trotzdem kann ich mir vorstellen, dass da irgendwie derselbe Hase im Busch ist.

Ich sehe mich lieber nach einer anderen Bibliothek für Charts um. Schade, denn die FX-Charts gefallen mir sehr gut. Vielleicht findet ja jemand noch was...
 

dzim

Top Contributor
Ich habe mir dein Beispiel noch einmal angeschaut und selbst kompiliert. Ich bekomme die Exception beim ersten Schliessen des neuen Fensters auch.
Danach nie wieder. Allerdings ist mein JavaFX-Content nie leer, wie von dir beschrieben.

Gibt es eigentlich unterschiede im Vergleich zum Update des Tutorials für JavaFX 8?
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/swing-fx-interoperability.htm

Ansonsten habe ich nach einer ersten Idee und der Beseitigung des genannten Problems, wie in diesem StackOverflow Eintrag hier beschrieben - http://stackoverflow.com/questions/11273773/javafx-2-1-toolkit-not-initialized - folgende alternative Lösung für dich.
Ob sie jetzt die allersauberste ist... Keine Ahnung. aber zum Einen funktioniert es und zum Anderen wolltest du ja anscheinend eh den FX-Teil auslagern.
Also:
Java:
package interop;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class SwingtInterop {
   
    private static void showStartGUI() {
        JFrame frame = new JFrame("Start");
        JButton showButton = new JButton("Show");
        // showButton.addActionListener(e -> initAndShowGUI());
        showButton.addActionListener(e -> Platform.runLater(() -> initAndShowJFXStage()));
        frame.add(showButton);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
   
    private static void initAndShowGUI() {
        // This method is invoked on the EDT thread
        JFrame frame = new JFrame("Swing and JavaFX");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       
        Platform.runLater(() -> initFX(fxPanel));
    }
   
    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }
   
    private static void initAndShowJFXStage() {
        Stage stage = new Stage(StageStyle.UTILITY);
        stage.setOnCloseRequest(windowEvent -> {
            // do something on Stage close?
        });
        stage.setScene(createScene());
        stage.showAndWait();
    }
   
    private static Scene createScene() {
        Group root = new Group();
        Scene scene = new Scene(root, Color.ALICEBLUE);
        Text text = new Text();
       
        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Welcome JavaFX!");
       
        root.getChildren().add(text);
       
        return (scene);
    }
   
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new JFXPanel();
            showStartGUI(); // ersetzt initAndShowGUI() aus dem Original
        });
    }
}

Was mache ich hier?
In SwingUtilities#invokeLater muss ich zwingend "new JFXPanel();" aufrufen, damit das JavaFX-Toolkit in dem Kontext initialisert ist. Ansonsten gibt es den Fehler "java.lang.IllegalStateException:Toolkit not initialized" (siehe dem StackOverflow-Eintrag).
Anstelle eines neuen Swing-Fensters lade ich nun eine neue Stage (das ist die JavaFX-Entsprechung eines Fensters - eben eine neue Bühne für die Daten).

Eventuell nutzt dir das etwas als Start-Punkt.

Ansonsten noch zwei Anmerkungen:
1) Warum eine gemischte Anwendung und nicht gleich vollständig auf JavaFX setzen (und wenn du "legacy" Swing-Code hast - die Interoperability von JavaFX erlaubet ab JavaFX 8 auch den umgekehrten Weg, also das einbetten von Swing in JavaFX)
2) Wenn du bei purem Swing bleiben willst, wäre ansonsten wohl JFreeChart eine gute Möglichkeit für dich. Extrem mächtig, etwas komplizierte API (finde ich) und nicht so leicht so gut zu gestalten wie JavaFX (kein CSS eben), aber vom Funktionumfang auch JavaFX deutlich überlegen - auch wenn es mittlerweile bereits Integrationen für JavaFX bereits gibt.
 

Hans_G

Mitglied
Danke, dzim, für die umfangreiche Antwort.

Dein Code lief auf meinem System ohne eine NPE beim Schließen des JFX-Fensters (Stage) zu werfen. Ich hatte zunächst das Problem, dass sich nach dem erstmaligen Schließen des JFX-Fensters, kein neues öffnen ließ, bin aber auf diesen Stackoverflow-Thread gestoßen: http://stackoverflow.com/questions/...thread-from-dying-with-jfxpanel-swing-interop

Ich habe dann Platform.setImplicitExit(false) im Runnable innerhalb von main() eingefügt (Platform.exit() muss dann korrekterweise noch ans Ende der Application angefügt werden) und dann ging alles wie gewünscht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Mehrere Panels auf JFrame AWT, Swing, JavaFX & SWT 8
M Seltsame Exception bei setVisible(true) Methode in einem JFrame AWT, Swing, JavaFX & SWT 2
Paty JFrame anfänger bräuchte hilfestellung AWT, Swing, JavaFX & SWT 7
Apfelbaum2005 Swing JFrame mehrere JPanels mit unterschiedlichen Formen hinzufügen AWT, Swing, JavaFX & SWT 1
N AWT JPanel zu Jframe hinzufügen AWT, Swing, JavaFX & SWT 2
Mausposition relativ zu JFrame bekommen AWT, Swing, JavaFX & SWT 6
sserio JFrame setIconImmage() funktioniert nicht AWT, Swing, JavaFX & SWT 3
N CPU Belastung bei offenem JFrame auf fast 100% AWT, Swing, JavaFX & SWT 15
N Knopf ganz oben (JFrame) AWT, Swing, JavaFX & SWT 9
N JFrame löscht alles, wenn groß gemacht AWT, Swing, JavaFX & SWT 9
N jFrame löscht am Ende des Threads alles AWT, Swing, JavaFX & SWT 2
N JFrame loescht alles, sobald der Thread zuende ist AWT, Swing, JavaFX & SWT 22
E JFrame resizing AWT, Swing, JavaFX & SWT 2
E Swing Mausposition auf einem JFrame erkennen AWT, Swing, JavaFX & SWT 5
Lunar Swing JFrame erstellt; weitere Elemente werden nicht eingefügt/sind nicht zu sehen AWT, Swing, JavaFX & SWT 4
L JFrame Gui in anderer Methode aufrufen AWT, Swing, JavaFX & SWT 0
H Beim JFrame erstellen ein anderes schließen AWT, Swing, JavaFX & SWT 0
H Daten aus einer XML(x83-Datei) in einem JFrame anzeigen lassen AWT, Swing, JavaFX & SWT 9
H Tabelle in JFrame einfügen AWT, Swing, JavaFX & SWT 1
VPChief Ein JFrame ohne setUndecorated(true); nicht verschiebbar machen. AWT, Swing, JavaFX & SWT 6
R Swing Hat mein JFrame meinen Component? AWT, Swing, JavaFX & SWT 2
R Swing Design des oberen Balkens in JFrame AWT, Swing, JavaFX & SWT 2
B KeyListener auf JFrame reagiert nicht AWT, Swing, JavaFX & SWT 8
R Swing Komponente im JFrame überschreinen sich AWT, Swing, JavaFX & SWT 7
R Swing Ein gezeichneten String aus dem JFrame löschen AWT, Swing, JavaFX & SWT 5
J Exception beim JFrame erstellen AWT, Swing, JavaFX & SWT 6
T JFrame aktualisieren AWT, Swing, JavaFX & SWT 2
T Bilder bei einem JFrame einfügen AWT, Swing, JavaFX & SWT 4
R Swing Background Image in JFrame implementieren AWT, Swing, JavaFX & SWT 40
L Verbindung von Code und JFrame AWT, Swing, JavaFX & SWT 4
L JFrame wird zu klein erstellt AWT, Swing, JavaFX & SWT 7
dereki2000 Swing JFrame nah hinzufügen von Komponenten akualisieren. AWT, Swing, JavaFX & SWT 2
T JFrame Bild einfügen AWT, Swing, JavaFX & SWT 9
T JavaFX JFrame verhalten wie JOptionPane (ErrorMessage) AWT, Swing, JavaFX & SWT 1
T LookAndFeel LookAndFeel funktioniert nicht beim JFrame wechsel AWT, Swing, JavaFX & SWT 3
P Swing Mehrere JPanels auf ein JFrame hinzufügen? AWT, Swing, JavaFX & SWT 2
F JFrame zeigt nicht alle Elemente auf anhieb an AWT, Swing, JavaFX & SWT 4
P JPanle, JFrame und Graphics AWT, Swing, JavaFX & SWT 2
T Reihenfolge der Komponenten im einem JFrame AWT, Swing, JavaFX & SWT 8
K Grafik in JFrame einpassen AWT, Swing, JavaFX & SWT 3
D Mit Jmenu neue JFrame öffnen AWT, Swing, JavaFX & SWT 2
J BackgroundJPanel passt sich dem JFrame nicht an AWT, Swing, JavaFX & SWT 7
C Swing JFrame ändert Größe AWT, Swing, JavaFX & SWT 0
J JFrame Panel hinzufügen AWT, Swing, JavaFX & SWT 10
K JFrame bei JUnit Tests AWT, Swing, JavaFX & SWT 2
W Swing Hilfe beim Einbinden von Bildern in einem JFrame AWT, Swing, JavaFX & SWT 8
D JFrame wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 1
R Swing JPanels auf JFrame auf verfügbaren Platz aufblasen AWT, Swing, JavaFX & SWT 4
JR2205 Swing JxMaps Einbindung Netbeans JFrame AWT, Swing, JavaFX & SWT 4
Zar von Domarus JFrame zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 3
K KeyListener ohne JFrame AWT, Swing, JavaFX & SWT 9
Joker4632 JFrame in eine Runnable auslagern? AWT, Swing, JavaFX & SWT 4
M Limit für JFrame-Vergrößerung AWT, Swing, JavaFX & SWT 8
GreenTeaYT Wie vergebe Ich den Jframe Title den Namen aus einem Element von der Arraylist ? AWT, Swing, JavaFX & SWT 4
MaxG. JFrame Größe ändern AWT, Swing, JavaFX & SWT 16
P Jframe Bild einfügen, Hintergrund Farbe ändern, und Button schrift Größe ändern AWT, Swing, JavaFX & SWT 2
G Swing Wenn ich mein JFrame Fenster vergrößere die Inhalte anpassen AWT, Swing, JavaFX & SWT 1
G JFrame Probleme AWT, Swing, JavaFX & SWT 2
Ghostman1711 JFrame closing AWT, Swing, JavaFX & SWT 3
R Engineklasse mit JFrame AWT, Swing, JavaFX & SWT 4
M Default-WindowListener JFrame entfernen (Stichwort: iconified) AWT, Swing, JavaFX & SWT 4
ms_cikar Jframe zurück zu frame1 AWT, Swing, JavaFX & SWT 14
C Jframe ohne Rahmen AWT, Swing, JavaFX & SWT 3
lumpigerAffe Swing Jframe aktualisieren AWT, Swing, JavaFX & SWT 27
A Swing JFrame neuzeichnen lassen, position neu berechnen lassen? AWT, Swing, JavaFX & SWT 9
R JFrame schließen AWT, Swing, JavaFX & SWT 9
P Swing JFrame minimiert sich bei Doppelklick auf die Titel-Leiste AWT, Swing, JavaFX & SWT 16
krgewb AWT JFrame soll sich wie Dialog verhalten AWT, Swing, JavaFX & SWT 9
I JFrame an Bildschirm anpassen AWT, Swing, JavaFX & SWT 1
I JFrame Bild strecken und auf Bildschirmgröße anpassen AWT, Swing, JavaFX & SWT 2
P JFrame schrumpft bei Doppelklick auf die Titelleiste AWT, Swing, JavaFX & SWT 0
G JFrame - manuell Größe verändern AWT, Swing, JavaFX & SWT 6
D JFrame mindestgröße erzwingen AWT, Swing, JavaFX & SWT 2
C Swing Borderlayout im JFrame AWT, Swing, JavaFX & SWT 4
B JButton erscheint in JFrame, obwohl er diesem nicht zugeordnet wurde! AWT, Swing, JavaFX & SWT 1
G Swing JFrame öffnen bei Pidgin Benachrichtigung AWT, Swing, JavaFX & SWT 5
OlafHD JLabel im JFrame Zentrieren AWT, Swing, JavaFX & SWT 2
S Kein JFrame unter Mac? AWT, Swing, JavaFX & SWT 8
G Resize JFrame AWT, Swing, JavaFX & SWT 8
J Teiltransparenter JFrame mit Blur-Effekt AWT, Swing, JavaFX & SWT 2
K Bild in JFrame AWT, Swing, JavaFX & SWT 2
V JScrollPane im zur Laufzeit verändernden JFrame AWT, Swing, JavaFX & SWT 0
M NetBeans JFrame Grundlangen fragen AWT, Swing, JavaFX & SWT 6
I Neues JFrame wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 5
S JFrame -> setVisible AWT, Swing, JavaFX & SWT 3
stylegangsta Eigene Klasse für JButton aus dem JFrame abrufen AWT, Swing, JavaFX & SWT 29
I Swing JMenuBar auch unten am JFrame? AWT, Swing, JavaFX & SWT 2
K SplashScreen neben JFrame behalten AWT, Swing, JavaFX & SWT 10
F Swing JLabel in JFrame anpassen AWT, Swing, JavaFX & SWT 20
B Swing Unterteiltes JFrame mit Bild in der Mitte AWT, Swing, JavaFX & SWT 4
H Netbeans Designer: Probleme mit JPanel und JFrame AWT, Swing, JavaFX & SWT 2
T Applet Applet in JFrame einbinden AWT, Swing, JavaFX & SWT 8
V JFrame wird nicht richtig angezeigt! AWT, Swing, JavaFX & SWT 2
I JFrame neu zeichnen, nicht überzeichnen! AWT, Swing, JavaFX & SWT 2
Y Kann man Buttons in einem JFrame rund machen ? AWT, Swing, JavaFX & SWT 2
W Swing Farbige JPanels auf JFrame werden nicht gezeigt. Was mach ich falsch? AWT, Swing, JavaFX & SWT 7
Z Java Draw -JFrame finde nicht die Mitte & höhe, breite AWT, Swing, JavaFX & SWT 7
O Swing JFrame Anzeigeproblem AWT, Swing, JavaFX & SWT 2
D jButton auf von jFrame erzeugtem jDialog AWT, Swing, JavaFX & SWT 16
J Swing unterschiedliche Inhalte in einem JFrame AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben