首页 > 解决方案 > JavaFX 无法在自定义加载器中加载 FXML

问题描述

我正在尝试使用 Spring 后端运行 JavaFx 前端。除了加载特定的 FXML 文件外,一切正常。加载其他的就像一个魅力。要设置 spring 和 javafx,我有以下功能:

public class FXMLSpringLoader{
  public Parent load(String pathToFXML) throws IOException{
    FXMLLoader loader = new FXMLLoader();
    //spring is now fxml controller factory
    loader.setControllerFactory(applicationContext::getBean);
    loader.setResources(resourceBundle);
    loader.setLocation(getClass().getResource(pathToFXML));

    return loader.load();
  }  
}  

以及StageManager处理设置场景等的类。每次调用该switchScene方法时,我都会得到一个NullPointerException.

public class StageManager {

    private final Stage stage;
    private final FXMLSpringLoader springLoader;

    public StageManager( FXMLSpringLoader fxmlSpringLoader, Stage stage){
        this.springLoader = fxmlSpringLoader;
        this.stage = stage;
    }

    public void switchScene(final View view){
        Parent rootNode = loadViewNode(view.getFxmlFile());
        show(rootNode, view.getTitle());
    }

    private Parent loadViewNode(String pathToFxml){
        Parent rootNode = null;

        try{
            rootNode = springLoader.load(pathToFxml);
        } catch (Exception e){
            exit("unable to load fxml " , e);
        }

        return rootNode;
    }

    private void show(final Parent rootNode, String title){

        Scene scene = prepareScene(rootNode);

        this.stage.setTitle(title);
        this.stage.setScene(scene);
        this.stage.sizeToScene();
        this.stage.centerOnScreen();

        try {
            stage.show();
        } catch (Exception exception) {
            exit ("error occured while showing scene: " + title,  exception);
        }

    }


    private void exit(String message, Exception ex){
        System.out.println(message + " " + ex.getCause());
        Platform.exit();
    }

    private Scene prepareScene(Parent rootnode){

        Scene scene = stage.getScene();

        if (scene == null) {
            scene = new Scene(rootnode);
        }
        scene.setRoot(rootnode);
        return scene;
    }
}

该方法在 Controller 中调用,如下所示:

stageManager.switchScene(View.PRODUCT);

我的视图类是一个枚举:

public enum View {

    PRODUCT {
        public String getTitle(){

          return ResourceBundle.getBundle("Bundle").getString("product.title");
        }

        public String getFxmlFile(){
            return "/fxml/Product.fxml";
        }

    };

     public abstract String getTitle();
     public abstract String getFxmlFile();


}

很抱歉发布了这么多代码,但我真的尝试了一切,但无法加载这个单一的 fxml。我已经尝试getClass().getClassLoader().getRes...并尝试将路径更改"/fxml/Product.fxml""resources/fxml/Product.fxml"or "../Product.fxml"。每一个帮助表示赞赏!
堆栈跟踪:

javafx.fxml.LoadException: 

/C:/Users/Alienware/Desktop/java/inventory%20management%20system/jFXSpring/target/classes/fxml/Product.fxml

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at com.kutuco.jFXSpring.config.FXMLSpringLoader.load(FXMLSpringLoader.java:36)
at com.kutuco.jFXSpring.config.StageManager.loadViewNode(StageManager.java:33)
at com.kutuco.jFXSpring.config.StageManager.switchScene(StageManager.java:25)
at com.kutuco.jFXSpring.config.StageManager$$FastClassBySpringCGLIB$$56b2684c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
at com.kutuco.jFXSpring.config.StageManager$$EnhancerBySpringCGLIB$$c9747e15.switchScene(<generated>)
at com.kutuco.jFXSpring.controller.LoginController.login(LoginController.java:50)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
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.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.graphics/javafx.scene.Node.fireEvent(Node.java:8865)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
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.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:3876)
at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
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:175)
at java.base/java.lang.Thread.run(Thread.java:844)

Caused by: java.lang.NullPointerException
at com.kutuco.jFXSpring.controller.ProductController.setColumns(ProductController.java:115)
at com.kutuco.jFXSpring.controller.ProductController.initialize(ProductController.java:106)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
... 68 more
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:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
... 47 more
Caused by: java.lang.NullPointerException: Scene's root cannot be null
at javafx.graphics/javafx.scene.Scene$8.invalidated(Scene.java:1222)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.graphics/javafx.scene.Scene.setRoot(Scene.java:1199)
at com.kutuco.jFXSpring.config.StageManager.prepareScene(StageManager.java:74)
at com.kutuco.jFXSpring.config.StageManager.show(StageManager.java:43)
at com.kutuco.jFXSpring.config.StageManager.switchScene(StageManager.java:26)
at com.kutuco.jFXSpring.config.StageManager$$FastClassBySpringCGLIB$$56b2684c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
at com.kutuco.jFXSpring.config.StageManager$$EnhancerBySpringCGLIB$$c9747e15.switchScene(<generated>)
at com.kutuco.jFXSpring.controller.LoginController.login(LoginController.java:50)
... 58 more

我的 ProductController 中的第 115 行:

public void setColumns(){
   ...
    colProductId.setCellValueFactory(new PropertyValueFactory<>("id"));
  ...
}

标签: javaspringjavafxfxml

解决方案


推荐阅读