JavaFX LoadException 解析事件

JavaFX LoadException resolving event

我一直在寻找答案,但是 none 的其他问题已经回答了我的问题。

我正在使用 SceneBuilder 在 JavaFX 中创建一个简单的应用程序(一个简单的表单)。遗憾的是我无法 运行 代码,因为它一直抛出 LoadException。

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: javafx.fxml.LoadException: Error resolving onAction='#login', either the event handler is not in the Namespace or there is an error in the script.
/D:/JavaApps/FormApp/out/production/FormApp/master/loginForm/loginForm.fxml:30

    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2703)
    at javafx.fxml/javafx.fxml.FXMLLoader$Element.processEventHandlerAttributes(FXMLLoader.java:620)
    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:780)
    at javafx.fxml/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2924)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2639)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2517)
    at JavaFxApplication/master.Main.start(Main.java:26)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:474)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:447)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:446)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop(WinApplication.java:174)
    ... 1 more
Exception running application master.Main

这是 FXML 内容 - 如您所见,我已经添加了控制器。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<GridPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="master.loginForm.LoginForm">
   <columnConstraints>
      <ColumnConstraints />
   </columnConstraints>
   <rowConstraints>
      <RowConstraints />
   </rowConstraints>
   <children>
      <Pane prefHeight="400.0" prefWidth="200.0">
         <children>
            <Label layoutX="26.0" layoutY="132.0" prefHeight="17.0" prefWidth="149.0" text="Surname" textAlignment="CENTER" />
            <Label layoutX="26.0" layoutY="6.0" prefHeight="17.0" prefWidth="149.0" text="Nick" textAlignment="CENTER" />
            <TextField fx:id="nickTF" layoutX="26.0" layoutY="25.0" promptText="Your awesome nick" />
            <Label layoutX="30.0" layoutY="71.0" prefHeight="17.0" prefWidth="141.0" text="Name" textAlignment="CENTER" />
            <TextField fx:id="nameTF" layoutX="26.0" layoutY="88.0" promptText="Name" />
            <TextField fx:id="surnameTF" layoutX="26.0" layoutY="149.0" promptText="Surname" />
            <Pane layoutY="200.0" prefHeight="59.0" prefWidth="200.0">
               <children>
                  <RadioButton fx:id="maleRB" layoutX="29.0" mnemonicParsing="false" text="Male" toggleGroup="$sexTG"></RadioButton>
                  <RadioButton fx:id="femaleRB" layoutX="29.0" layoutY="29.0" mnemonicParsing="false" text="Female" toggleGroup="$sexTG" />
               </children>
            </Pane>
            <TextField fx:id="emailTF" layoutX="26.0" layoutY="280.0" promptText="email@gra.pl" />
            <Label layoutX="26.0" layoutY="259.0" prefHeight="17.0" prefWidth="149.0" text="Email" textAlignment="CENTER" />
            <Button fx:id="loginBT" defaultButton="true" layoutX="74.0" layoutY="336.0" onAction="#login" text="Login"> </Button>
         </children>
      </Pane>
      <Pane fx:id="exceptionNotifyPane" layoutX="200.0" layoutY="14.0" prefHeight="164.0" prefWidth="149.0" />
   </children>
</GridPane>

这是控制器的内容 - 请注意,我已经尝试了使用和不使用 ActionEvent 参数的两种方法,以防它可能是问题所在,但显然不是。

package master.loginForm;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.Pane;

public class LoginForm {

    @FXML
    private TextField nameTF;

    @FXML
    private TextField surnameTF;

    @FXML
    private TextField emailTF;

    @FXML
    private TextField nickTF;

    @FXML
    private Pane exceptionNotifyPane;

    @FXML
    private ToggleGroup sexTG;

    @FXML
    private Button loginBT;

    @FXML
    public void initialize(){

    }

    @FXML
    public void login(ActionEvent event){

    }
}

最后是主要内容。

package master;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.LoadException;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import master.loginForm.LoginForm;

import java.net.URL;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        try {
            primaryStage.setTitle("Login Form");

            URL resource = LoginForm.class.getResource("loginForm.fxml");

            FXMLLoader loader = new FXMLLoader(resource);
            loader.setControllerFactory(param -> this);
            loader.setClassLoader(getClass().getClassLoader());

            Parent root = loader.load();

            Scene scene = new Scene(root);

            primaryStage.setScene(scene);
            primaryStage.show();

        }catch (LoadException loadException){
            System.out.println("LoadException occurred " + loadException.getMessage());
            return;
        }
        catch(Exception e){
            System.out.println("Exception occurred: " + e.getClass().getSimpleName() + "\n" + e.getMessage());
            return;
        }
    }

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

我之前在使用这段代码时遇到过同样的异常问题,通过从 FXML 中删除 fx:controller 行“解决”了这个问题。显然,一旦代码中需要进行事件处理,这就成了一个问题。我试图在控制器内部实现 evenHandler,但这并没有奏效,导致了相同的异常。经过数小时的研究并未能找到解决方案,我很乐意接受任何帮助,谢谢。

对于那些寻求相同问题答案的人,我可能会为您提供解决方案。 “从头开始”创建完全相同的项目导致了同样的问题。

我的解决方案是更新项目的 SDK(使用我的 IDE 重新下载)。

编辑 1:
正如 kleopatra 在评论中所说,值得一提的是我 错误地使用了 setControllerFactory。我从我的代码中完全删除了那部分,并且只在 FXML 文件中设置了控制器。

编辑 2:
结果证明之前的解决方案根本不是解决方案

首先确保您正在正确创建新的 window

在我的例子中,我创建了这样的函数:

private void createNewWindow(String resource, String title) {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(resource));
            Parent newRoot = fxmlLoader.load();
            Stage stage = new Stage();
            stage.setTitle(title);
            stage.setScene(new Scene(newRoot));
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

需要时可以简单调用:

createNewWindow("/resources/fxmFile.fxml", "Window Title");

确保您正确引用了 .fxml 文件

其次确保您在 FXML 文件中添加了控制器。

<AnchorPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="main.packagename.ControllerName"
>
...
</AnchorPane>

最后确保您的 module-info.java 文件配置正确:

    //all necessary java requires including those below
    requires javafx.base;
    requires javafx.graphics;
    requires javafx.fxml;
    requires javafx.controls;

    //assuming your main package is called 'main'
    exports main;
    opens main;

    exports main.subPackageName;
    opens main.subPackageName;
    ...
    exports main.otherSubPackageName;
    opens main.otherSubPackageName;

此外请确保 将您的 java.fx lib 文件夹包含在您的 IDE.

这解决了我所有的问题,希望有一天能对某人有所帮助 ;)。