Не удается загрузить FXML в другой пакет (JavaFX) - PullRequest
0 голосов
/ 10 декабря 2018

По какой-то причине я получаю сообщение об ошибке при попытке загрузить FXML, который находится в другом пакете:

MainApp.java"

FXMLLoader loader = new FXMLLoader();

            System.out.println("view folder: " + MainApp.class.getResource("view/RootLayout.fxml"));     // returns null
            loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml"));

Структура папки:

enter image description here

Сообщение об ошибке:

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:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        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:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
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:834)
Caused by: java.lang.IllegalStateException: Location is not set.
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
        at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
        at checkmydigitalfootprint.MainApp.initRootLayout(MainApp.java:73)
        at checkmydigitalfootprint.MainApp.start(MainApp.java:55)
        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:455)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
        at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application checkmydigitalfootprint.MainApp

1 Ответ

0 голосов
/ 10 декабря 2018

Я могу сказать вам, что работает для меня.Во-первых, файлы FXML следует рассматривать как ресурсы, а не как исходные файлы Java, поэтому их лучше размещать в своем собственном дереве каталогов.Ваш исходный код в настоящее время находится в дереве /src/main/java, поэтому ваши файлы FXML должны быть перемещены в дерево /src/main/resources, в идеале в подкаталог с именем fxml.(У меня также есть подкаталог с именем i18n, в котором содержатся пакеты ресурсов для определения текстовых меток на нескольких языках.)

Как только ваши файлы FXML будут найдены по пути /src/main/resources/fxml, вы сможете загрузить их изваши контроллеры JavaFX примерно так:

FXMLLoader loader = new FXMLLoader();
URL fxmlLocation = getClass().getResource("/fxml/main_screen.fxml");
loader.setLocation(fxmlLocation);
loader.setController(mainScreenController);
loader.setResources(ResourceBundle.getBundle("i18n/Text", new Locale("sv", "SE")));
Pane pane = loader.<Pane>load();
Scene scene = new Scene(pane);

(Если корневой элемент вашего файла FXML не представляет Pane, вам нужно изменить строку, которая вызывает метод load(),и замените Pane на соответствующий тип.)

Обратите внимание, что вызов getResource(String) принимает путь, который начинается с косой черты и представляет корень пути ресурса /src/main/resources/.

И также обратите внимание, что, как ни странно, вызов getBundle(String) действительно , а не начинается с косой черты, даже если вы нацелены на точно такой же путь /src/main/resources/.Я должен признать, что не могу объяснить, почему эти два метода нужно обрабатывать немного по-разному, как этот, но этот код работает для загрузки как файла "main_screen.fxml", так и файла пакета ресурсов шведского языка "Text_sv_SE.properties".

...