我正在尝试加载FXML文件并将其显示为应用程序窗口,但我得到一个例外。 FXML文件由FXML Scene Builder创建。
以下是班级的代码
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(FXMLLoader.load(getClass().getResource("sample.fxml")));
primaryStage.show();
}
}
和FXML文件
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0" text="Pass4D" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/8">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Button layoutX="211.0" layoutY="134.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="177.0"
text="Log in"/>
<Button layoutX="212.0" layoutY="170.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="175.0"
text="Exit"/>
</children>
</AnchorPane>
</content>
</TitledPane>
这是我得到的例外
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
at com.sun.javafx.application.LauncherImpl$$Lambda$1/2074407503.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3201)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3169)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3142)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3118)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3098)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3091)
at Pass4D.start(Pass4D.java:19)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
at com.sun.javafx.application.LauncherImpl$$Lambda$51/317090070.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1833150059.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$49/2115863517.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1436737924.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
我做错了什么?
P.S。这是项目结构
答案 0 :(得分:15)
如果在运行时 classpath 上找不到资源,那么简短的答案是getClass().getResource("sample.fxml")
静默返回null
。
所以这取决于您的IDE项目设置,如果您正在使用eclipse尝试添加sample.fxml
驻留在运行配置中的文件夹。
一些想法......
getClass().getResource("/sample.fxml")
而不是...... sample.fxml
移动到资源文件夹中。我不太了解您的IDE,但我怀疑该文件夹仅用于.java
文件...这对于eclipse中的gradle项目来说确实如此 - 资源必须位于{{1}树只作为添加到运行时类路径... 答案 1 :(得分:2)
我今天已经发布了这个,所以又来了,希望它可以帮到你。
这是一个适用于开发环境,Scene Builder和打包的JAR中的解决方案。
文件夹结构:
Main.java:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view/RootLayout.fxml"));
AnchorPane rootLayout = (AnchorPane) loader.load();
Scene scene = new Scene(rootLayout, 400, 400);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
RootLayout.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.view.RootLayoutController">
<children>
<Pane layoutX="0.0" layoutY="0.0" prefHeight="200.0" prefWidth="200.0">
<children>
<Button fx:id="sunButton" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" onAction="#handleSunButtonClick" styleClass="sun-button" stylesheets="@../css/toolbar.css" text="Button" />
</children>
</Pane>
</children>
</AnchorPane>
RootLayoutController.java:
package application.view;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class RootLayoutController {
@FXML
Button sunButton;
@FXML
public void handleSunButtonClick() {
System.out.println( "Button clicked");
}
}
toolbar.css:
.sun-button {
-fx-graphic: url('./icons/sun.png');
}
application.css:
.root {
-fx-background-color:lightgray;
}
sun.png:
这适用于开发环境和打包JAR(在Eclipse中选择“将所需库提取到生成的JAR中”)。
屏幕截图(只是一个带有通过css加载图标的按钮)
答案 2 :(得分:1)
从oracle尝试这个例子:
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));
Scene scene = new Scene(root, 300, 275);
stage.setTitle("FXML Welcome");
stage.setScene(scene);
stage.show();
}
答案 3 :(得分:0)
Main.class.getResource为我工作。我试图从子类而不是从主类获取资源。我在那里使用了getClass()。getResource(),它指向当前类。我的资源目录中没有FXML文件。
答案 4 :(得分:0)
将MainApp.class附加到getClass()。getResource(“ / fxml / Scene.fxml”)。为我工作! 例: 父根= FXMLLoader.load(MainApp.class.getClass()。getResource(“ / fxml / Scene.fxml”));
答案 5 :(得分:0)
删除您的 javafx 项目中的“build”文件夹并重建您的项目。
答案 6 :(得分:0)
如果您使用 Maven,您可能需要将 fxml 文件移动到您的资源目录。
refactor src/main/java/sample/sample.fxml to src/main/resources/sample/sample.fxml