0

I'm building a Swing application and I'm using JFXPanel to bring up a WebView for user authentication. I need to return the url that the WebEngine is sent to after a successful user sign-on- but I don't know how to pull the URL from the view at the time the window is closed. I'm aware of Stage.setOnHiding, but this can't apply here since JFXPanels don't act as stages, though they contain a scene.

I'm very new to JavaFX so if this code snippet demonstrates bad conventions, I'd be happy to hear it!

private static void buildAuthBrowser() {
        JFrame frame = new JFrame("frame");
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                initFX(fxPanel);
            }
        });

    }

    private static void initFX(JFXPanel fxPanel) {
        // fx thread
        Scene scene = createScene();

        fxPanel.setScene(scene);

    }

    private static Scene createScene() {
        Group root = new Group();
        Scene scene = new Scene(root);
        WebView view = new WebView();
        WebEngine browser = view.getEngine();
        browser.load(auth.getUrl());
        root.getChildren().add(view);
        return (scene);
    }
  • Your `JFXPanel` is in a `JFrame`. Just react to the `JFrame` closing. – James_D Aug 19 '22 at 21:05
  • This was my first thought, but then how do I go about accessing the WebEngine object that is defined within the createScene method? I tried declaring the engine and view globally, but then I run into issues with the javaFX thread not having started yet. thanks! – Grant Sanders Aug 19 '22 at 21:14
  • Not sure the problem. Just declare them as instance variables. – James_D Aug 19 '22 at 21:24

1 Answers1

0

Found a solution- I was able to set a listener on the engine in the scene builder method, this way, every time the browser visits a new URL it automatically updates a private variable.

in createScene():

authBrowser.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
            if (Worker.State.SUCCEEDED.equals(newValue)) {
                setCode(authBrowser.getLocation());
            }
        });
  • To avoid potential thread issues, it is probably a good idea to run your `setCode` method on the [swing event dispatch thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html), using [invokeLater](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)). – jewelsea Aug 20 '22 at 06:19