【问题标题】:JavaFX LoadException resolving eventJavaFX LoadException 解决事件
【发布时间】:2021-05-11 10:31:01
【问题描述】:

我一直在寻找答案很长时间,但是其他问题都没有回答我的问题。

我正在使用 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$2(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$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:474)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:447)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(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$3(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 ,但这也不起作用,导致相同的异常。经过数小时的研究和未能找到解决方案,我很乐意接受任何帮助,谢谢。

【问题讨论】:

  • 删除控制器出厂声明loader.setControllerFactory(param -&gt; this);时有效
  • @anko 遗憾的是它没有,异常仍然发生
  • minimal reproducible example 请......包括完整的堆栈跟踪(不要吞下它,也不要只打印它的消息)
  • @kleopatra 对此感到抱歉,我已经把整个堆栈跟踪(如果我没记错的话)
  • 不是很小但足够短,可以查看它:) 好奇(目前没有 IDE 可以自己尝试,sry):为什么要设置控制器工厂和类加载器?如果不这样做会怎样?

标签: java exception javafx scenebuilder


【解决方案1】:

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

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

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

编辑 2:
事实证明,之前的解决方案根本不是解决方案

首先确保您正确地创建了新窗口

就我而言,我创建了这样的函数:

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;

另外确保在你的IDE中包含你的java.fx lib文件夹

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

【讨论】:

  • @kleopatra 它没有,但是问题的根源不是错误的使用;我确实从我的代码中删除了它,我会将该提示添加到答案中,以便其他人也知道这一点。
猜你喜欢
  • 1970-01-01
  • 2016-01-07
  • 2019-09-19
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多