Search code examples
javajavafxjxbrowser

LoadException when loading fxml files with Java Bridge API


I want to open new JavaFX window after user performs certain action in JxBrowser. Example code of the Java object that I insert to Javascript

public class JavaApp {
    public void openNewWindow() {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("new-window.fxml"));
        Parent root = null;
        try {
            root = loader.load();
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        Stage newStage = new Stage();
        newStage.setTitle("New window");
        newStage.setScene(new Scene(root, 100, 100));
        newStage.show();
    }
}

After calling openNewWindow from Javascript I get the following stacktrace:

javafx.fxml.LoadException: /home/asdfzxc/Projects/JxBrowserError/out/production/JxBrowserError/sample/new-window.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at sample.Controller$JavaApp.openNewWindow(Controller.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.teamdev.jxbrowser.chromium.JSContext.a(SourceFile:1446)
at com.teamdev.jxbrowser.chromium.JSContext$a.onMessageReceived(SourceFile:280)
at com.teamdev.jxbrowser.chromium.internal.ipc.p.a(SourceFile:1082)
at com.teamdev.jxbrowser.chromium.internal.ipc.q.run(SourceFile:66)
at com.teamdev.jxbrowser.chromium.internal.q.run(SourceFile:63)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at javafx.fxml.FXMLLoader.loadTypeForPackage(FXMLLoader.java:2916)
at javafx.fxml.FXMLLoader.getType(FXMLLoader.java:2870)
at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2758)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2704)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 17 more

Opening new window works if the code is called from inside JavaFX controller though. What should I do so that FXMLLoader works in this case?


Solution

  • I think I found the answer myself. The problem apparently was that this code should be run in JavaFX thread. It can be done this way:

    public class JavaApp {
        public void openNewWindow() {
            Platform.runLater(() -> {
                try {
                    FXMLLoader loader = new FXMLLoader(getClass().getResource("new-window.fxml"));
                    Parent root = loader.load();
                    Stage newStage = new Stage();
                    newStage.setTitle("New window");
                    newStage.setScene(new Scene(root, 100, 100));
                    newStage.show();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }