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:
Beim Schließen des JFrames mit JFXPanel, passiert entweder
1: Eine NullPointerException wird geworfen:
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?
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)
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?