我的Maven项目JavaFx模块化后,我无法从资源中获取fxmls

问题描述

当我将maven项目移至模块化模式时,它开始出现一个错误,每次我尝试从资源中获取fxml来切换场景时都会引发错误

奇怪的是,我可以从主类中获取fxml资源,而不能从控制器包中的Utils自定义类中获取fxml资源。在履历表中,我可以加载第一个场景,但是当我尝试切换到另一个场景时,我的应用程序崩溃了。我已经尝试了在堆栈中找到的所有解决方案,但没有任何解决方案可以解决我的问题。

MainClass中的打印内容getClass()。GetResource(“ fxml / tab_menu.fxml”):

file:/home/arantesandre97/Developer/certeducSignerApp/target/classes/com/certeduc/fxml/tab_menu.fxml

UtilsClass Utils.class.GetResource(“ ../ fxml / login.fxml”)中的打印内容

null

我的项目文件Java Project Files

我的项目模块:

module signerapp {
    requires transitive javafx.controls;
    requires javafx.fxml;
    requires com.jfoenix;
    requires org.kordamp.iconli.core;
    requires org.kordamp.ikonli.fontawesome;
    requires org.kordamp.ikonli.fontawesome5;
    requires org.kordamp.ikonli.javafx;

    opens com.certeduc.controller to javafx.fxml;
    exports com.certeduc;
}

我的Maven配置:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.certeduc</groupId>
    <artifactId>signerapp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>signerapp</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>11</maven.compiler.release>
        <javafx.version>13</javafx.version>
    </properties>

    <organization>
        <!-- Used as the 'vendor' for JNLP generation -->
        <name>Your Organisation</name>
    </organization>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>com.jfoenix</groupId>
            <artifactId>jfoenix</artifactId>
            <version>9.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-core</artifactId>
            <version>11.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-javafx</artifactId>
            <version>11.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-fontawesome-pack</artifactId>
            <version>11.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-fontawesome5-pack</artifactId>
            <version>11.5.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${maven.compiler.release}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <configuration>
                    <release>${maven.compiler.release}</release>
                    <jlinkImageName>signerapp</jlinkImageName>
                    <launcher>launcher</launcher>
                    <mainClass>com.certeduc.MainApp</mainClass>
                    <options>
                        <option>--add-opens</option>
                        <option>javafx.graphics/com.sun.javafx.scene=com.jfoenix</option>
                        <option>--add-opens</option>
                        <option>javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix</option>
                        <option>--add-opens</option>
                        <option>javafx.controls/com.sun.javafx.scene.control=com.jfoenix</option>
                        <option>--add-opens</option>
                        <option>javafx.base/com.sun.javafx.binding=com.jfoenix</option>
                        <option>--add-opens</option>
                        <option>javafx.graphics/com.sun.javafx.stage=com.jfoenix</option>
                        <option>--add-opens</option>
                        <option>javafx.base/com.sun.javafx.event=com.jfoenix</option>
                        <option>--add-exports</option>
                        <option>javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix</option>
                        <option>--add-exports</option>
                        <option>javafx.controls/com.sun.javafx.scene.control=com.jfoenix</option>
                        <option>--add-exports</option>
                        <option>javafx.base/com.sun.javafx.binding=com.jfoenix</option>
                        <option>--add-exports</option>
                        <option>javafx.graphics/com.sun.javafx.stage=com.jfoenix</option>
                        <option>--add-exports</option>
                        <option>javafx.base/com.sun.javafx.event=com.jfoenix</option>
                    </options>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

我的主班:

package com.certeduc;

import java.io.IOException;

import com.certeduc.controller.Utils;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;


public class MainApp extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("fxml/tab_menu.fxml")); //Here I can access the file perfectly ("../fxml/tab_menu.fxml")

        Image appIcon = new Image(getClass().getResourceAsstream("icons/signature_icon_256.png"));
        stage.getIcons().add(appIcon);
        
        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource("styles/styles.css").toExternalForm());
        
        stage.setTitle("SignerApp");
        stage.setScene(scene);
        stage.show();

        Utils.setwindowMinimumSize(stage,scene);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

我的UtilsClass:

package com.certeduc.controller;

import java.io.IOException;

import javafx.event.Event;
import javafx.fxml.FXMLLoader;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class Utils {
    private static Bounds getPrefBounds(Node node) {
        double prefWidth;
        double prefheight;

        Orientation bias = node.getContentBias();
        if (bias == Orientation.HORIZONTAL) {
            prefWidth = node.prefWidth(-1);
            prefheight = node.prefheight(prefWidth);
        } else if (bias == Orientation.VERTICAL) {
            prefheight = node.prefheight(-1);
            prefWidth = node.prefWidth(prefheight);
        } else {
            prefWidth = node.prefWidth(-1);
            prefheight = node.prefheight(-1);
        }
        return new BoundingBox(0,prefWidth,prefheight);
    }

    public static void setwindowMinimumSize(Stage stage,Scene scene)
    {
        Node root = scene.getRoot();
        Bounds rootBounds = root.getBoundsInLocal();
        double deltaW = stage.getWidth() - rootBounds.getWidth();
        double deltaH = stage.getHeight() - rootBounds.getHeight();

        Bounds prefBounds = getPrefBounds(root);

        stage.setMinWidth(prefBounds.getWidth() + deltaW);
        stage.setMinHeight(prefBounds.getHeight() + deltaH);
    }

    public static void centerOnScreen(Stage stage) {
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX((screenBounds.getWidth() - stage.getWidth()) / 2);
        stage.setY((screenBounds.getHeight() - stage.getHeight()) / 2);
    }

    public static Stage getwindow(Event event) {
        return (Stage) ((Node) event.getSource()).getScene().getwindow();
    }

    public static void switchWindow(Event event,String targetFxmlName) throws IOException {
        //Todo fix the bug which makes the fxmls  this class (Error: Location is required at line 63)
        Parent root = FXMLLoader.load(Utils.class.getResource("../fxml/" + targetFxmlName + ".fxml")); // THE ERROR IS HERE,and before modularize my project,this line was working pretty fine
        Scene scene = new Scene(root);

        Stage stage = Utils.getwindow(event);

        stage.setScene(scene);
        centerOnScreen(stage);
        stage.show();

        setwindowMinimumSize(stage,scene);
    }
}

我尝试了Utils.class.getResources(“”),但只能访问到(“ ../com/certeduc/controller”),之后才尝试使用Utils.class.getResources(“ ../ fmxl / fxmlName.fxml“),但即使将fxml处理到控制器文件夹我也无法访问

[INFO] Scanning for projects...
[INFO] 
[INFO] -----------------------< com.certeduc:signerapp >-----------------------
[INFO] Building signerapp 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ signerapp ---
[INFO] Deleting /home/arantesandre97/Developer/certeducSignerApp/target
[INFO] 
[INFO] --- javafx-maven-plugin:0.0.3:run (default-cli) @ signerapp ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] copying 8 resources
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 8 source files to /home/arantesandre97/Developer/certeducSignerApp/target/classes
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
        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:8890)
        at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
        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:3862)
        at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
        at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2590)
        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(Native Method)
        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:412)
        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.gtk.GtkApplication._runLoop(Native Method)
        at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
        at java.base/java.lang.Thread.run(Thread.java:834)
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:566)
        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:566)
        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:1782)
        ... 46 more
Caused by: java.lang.NullPointerException: Location is required.
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106)
        at [email protected]/com.certeduc.controller.Utils.switchWindow(Utils.java:63)
        at [email protected]/com.certeduc.controller.TabMenuController.exitApp(TabMenuController.java:77)
        ... 57 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  9.408 s
[INFO] Finished at: 2020-11-09T18:20:33-03:00
[INFO] ------------------------------------------------------------------------

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)