0

I am making a simple JavaFX project and I've hit a snag in trying to get my application to change scenes when clicking on a menu item after attaching an onAction event. My troubleshooting process went this way:

public void onAddNewFacilityMenuItemClick(ActionEvent event) throws IOException {
    System.out.println("clicked \"add facility\"");
}

When I click on the "Add Facility" menu item, "add facility" is printed to the console. This is good, it shows that the controller is properly connected to the fxml file.

After this, I tried a block of code from YouTube that worked fine when following the tutorial:

public void switchToScene1(ActionEvent event) throws IOException {
    root = FXMLLoader.load(getClass().getResource("Scene1.fxml"));
    stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
    scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

In the tutorial, the handler was attached to a button and when the button was clicked, the scene was changed from "Scene2.fxml" (the source of the event in line 3) to "Scene1.fxml" (the resource loaded into the "root" variable). This worked perfectly fine.

However, when I tried it with my own code, I got a fairly large stack trace (below)

public void onAddNewFacilityMenuItemClick(ActionEvent event) throws IOException {
     root = FXMLLoader.load(getClass().getResource("add-facility.fxml"));
     stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
     scene = new Scene(root);
     stage.setScene(scene);
     stage.show();
}

The differences between my code and the tutorial instructor's is that he is using a Button's event handler while I am using a MenuItem's event handler. Beside that, everything seems the same. Each FXML view I have works on its own, but the MenuItem switch seems to not work. I even tried using the FXML view ("add-facility") in the tutorial project and that worked (once I removed the controller dependency). It appears that the biggest hurdle is the MenuItem which doesn't seem to translate to a Node/Stage.

Stack trace:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: 
java.lang.reflect.InvocationTargetException
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1856)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1723)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.controls/javafx.scene.control.MenuItem.fire(MenuItem.java:459)
at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1385)
at javafx.controls/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(ContextMenuContent.java:1338)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3861)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1854)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2587)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:413)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:833)
    Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at  java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1851)
... 42 more
    Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3310)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3274)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3243)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3216)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3193)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3186)
at com.jwald.logplanner/com.jwald.logplanner.controllers.AddTripController.onAddNewTruckMenuItemClick(AddTripController.java:54)
... 53 more
jwald3
  • 19
  • 1
  • 6
  • The stack trace indicates your code is actually failing before the point where it would fail because you're using a `MenuItem` (which, as you correctly observe, is not a `Node`, so can't be cast to one). It's failing at line 54, which should be `root = FXMLLoader.load(...)`, according to the stack trace. You need to fix the issue with the FXML path: see https://stackoverflow.com/questions/61531317/how-do-i-determine-the-correct-path-for-fxml-files-css-files-images-and-other. Then use the duplicate to fix the problem you actually describe... – James_D Dec 02 '21 at 16:23
  • @James_D what would cause the FXML to be null when accessed from the controller but not from the view? The controller and application are in separate packages from each other, but both are separate from the FXML files. I don't get what's causing an issue there – jwald3 Dec 02 '21 at 16:37
  • Obviously if they are in different packages, and you’re using a relative path to the resource, they can’t possibly both work. (The FXML can’t be in the same package as both the classes, if the classes are in different packages…) – James_D Dec 02 '21 at 16:43
  • 1
    If you know it works from some class, let’s call it `App`, why don’t you just do `App.class.getResource(…)` instead of `getClass().getResource(…)`? – James_D Dec 02 '21 at 16:54

0 Answers0