javaswingjavafxfxmlloaderjfxpanel

How to run Javafx stage/scene in Swing Application?


I have a swing application where I need to run and open JavaFX Scene/stage. I have to run it without extends Application. I've tried most of the solutions posted on Stackoverflow, none of them are working in my situation.

Here is my latest try and I am getting NullPointerException. My stage is getting NULL. This line -> [stage.setScene(new Scene(root, SCENEWIDTH, SCENEHEIGHT));]

How to resolve this issue at this point? Or is there any elegant way to resolve this issue? Here is the block of code:

case ADMIN:
      new JFXPanel();
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/AdminView.fxml"));
                        Parent root = loader.load();
                        stage.setScene(new Scene(root, SCENEWIDTH, SCENEHEIGHT));
                        // Give the controller access to the main app
                        AdminController controller = loader.getController();
                        controller.setMainApp();
                        stage.show();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

break;

Any help would be greatly appreciated.


Solution

  • Don't use a Stage in a Swing application; instead, use a JFrame and embed the JavaFX content inside it using a JFXPanel:

    case ADMIN:
    
        // I'm assuming this code is on the AWT Event Dispatch thread
    
        JFrame window = new JFrame();
        JFXPanel jfxPanel = new JFXPanel();
        Platform.runLater(() -> {
    
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/AdminView.fxml"));
                Parent root = loader.load();
                jfxPanel.setScene(new Scene(root, SCENEWIDTH, SCENEHEIGHT));
                // Give the controller access to the main app
                AdminController controller = loader.getController();
                controller.setMainApp();
    
                SwingUtilities.invokeLater(() -> {
                    window.add(jfxPanel);
                    window.pack();
                    window.setVisible(true);
                });
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        });
    
    break;