Исключение "Место требуется" при загрузке файла FXML
Я пытаюсь загрузить файл 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. вот структура проекта
![enter image description here]()
Ответы
Ответ 1
Короткий ответ getClass().getResource("sample.fxml")
без null
возвращает null
, если ресурс не может быть найден во время выполнения classpath, а не текущий каталог и т.д.
Так что это зависит от настройки вашего проекта IDE, если вы используете eclipse, попробуйте добавить папку, в которой sample.fxml
находится в конфигурации запуска.
Некоторые идеи...
- попробуйте
getClass().getResource("/sample.fxml")
вместо этого...
- попробуйте переместить
sample.fxml
в папку ресурсов. Я мало знаю о вашей среде IDE, но я подозреваю, что папка используется только для файлов .java
... это, безусловно, верно для проектов gradle в eclipse - ресурсы должны быть в дереве src/main/resources
, как только который добавляется к пути пути выполнения...
Ответ 2
Я уже разместил это сегодня, так что и здесь, надеюсь, это поможет вам.
Вот решение, которое работает в среде разработки, в Scene Builder и в упакованном JAR.
Структура папок:
![enter image description here]()
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:
![enter image description here]()
Это работает как в среде разработки, так и при упаковке JAR (выберите "Извлечь требуемые библиотеки в сгенерированный JAR" в Eclipse).
Снимок экрана (только кнопка со значком, загружаемым через css)
![enter image description here]()
Ответ 3
Попробуйте этот пример из 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();
}
Ответ 4
Main.class.getResource работал для меня. Я пытался получить ресурс из подкласса вместо основного. Я использовал getClass(). GetResource(), который указывал на текущий класс. У меня не было файлов FXML в каталоге ресурсов.