我一直在寻找答案,但其他问题都没有答案。
我正在使用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,但这也不起作用,导致了相同的Exception。经过数小时的研究和未能找到解决方案,我很乐意接受任何帮助,谢谢。
对于那些寻求同一问题答案的人,我可能会为你找到解决方案。创建完全相同的项目";"从头开始";导致了同样的问题。
对我来说,解决方案是更新项目的SDK(使用我的IDE重新下载(
第1版:
正如kleopatra在评论中所说,值得一提的是,我错误地使用了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>
最后,确保您的模块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文件夹。
这已经解决了我所有的问题,希望有一天它能帮助到别人;(。