Как исправить «java.lang.IllegalStateException: Местоположение не установлено» для проекта JavaFX в eclipse - PullRequest
2 голосов
/ 31 мая 2019

Я создал проект JavaFX в Eclipse, где я храню код Java в папке src, а файлы fxml - в папке ресурсов. Есть несколько компонентов пользовательского интерфейса, которые не имеют соответствующих файлов fxml, например, пользовательская кнопка.

Когда я пытаюсь импортировать такие компоненты в файлы fxml, я получаю следующую ошибку Вызвано: java.lang.IllegalStateException: Местоположение не установлено.

Я рассмотрел много проблем с ошибкой «java.lang.IllegalStateException: Location is set», но не смог найти ту же проблему, с которой сталкиваюсь.

Для простоты я воспроизвел ошибку с меньшим проектом, где древовидная структура папок src выглядит следующим образом

     ── src
        ├── application
        │   └── Main.java
        ├── component
        │   └── RoundedButton.java
        ├── ui
        │   └── UIHomePage.java
        └── widget
            └── ListComboBox.java

и древовидная структура папки ресурсов выглядит следующим образом

     ── resources
        ├── ui
        │   └── UIHomePage.fxml
        └── widget
            └── ListComboBox.fxml

Main.java содержит метод start, который может загрузить файл UIHomePage.fxml, контроллером для которого является UIHomePage.java.

RoundedButton.java расширяет класс javafx.scene.control.Button и не использует отдельный файл fxml.

ListComboBox.java расширяет javafx.scene.layout.GridPane и использует ListComboBox.fxml в качестве ресурса fxml.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь загрузить resources / ui / UIHomePage.fxml, он не может определить, где находится ListComboBox, потому что он каким-то образом не может найти src / widget / ComboBox.

У меня есть и папки src, и ресурсы, добавленные как Source в Java Build Path.

Main.java (код метода запуска, загружающий fxml-файл только для UIHomePage.fxml)

    Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("ui/UIHomePage.fxml"));

UIHomePage.fxml

    <?import javafx.scene.layout.GridPane?>
    <?import component.RoundedButton?>
    <?import widget.ListComboBox?>

    <GridPane fx:controller="ui.UIHomePage" xmlns:fx="http://javafx.com/fxml" alignment="center">
        <GridPane GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="1" GridPane.halignment="CENTER" visible="true" vgap="10" hgap="10">
            <ListComboBox  fx:id="cityName" GridPane.columnIndex="1" GridPane.rowIndex="0" GridPane.columnSpan="2" GridPane.rowSpan="1"/>
            <RoundedButton fx:id="addButton"     GridPane.columnIndex="1" GridPane.rowIndex="2" GridPane.columnSpan="1" GridPane.rowSpan="1" text="Add Property"     defaultButton="true" onAction="#handleAddProperties"/>
        </GridPane>
    </GridPane>

UIHomePage.java

    import widget.*;
    public class UIHomePage {
        @FXML private ListComboBox  cityName;
        @FXML
        public void initialize() throws Exception{
            cityName.setPrefWidth(GridPane.REMAINING);
        }
        @FXML
        protected void handleAddProperties(ActionEvent event) throws Exception {
            //DO SOMETHING
        }
    }

ListComboBox.fxml

    <fx:root type="javafx.scene.layout.GridPane" xmlns:fx="http://javafx.com/fxml">
        <ComboBox fx:id="comboBox" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
    </fx:root>

ListComboBox.java

    public class ListComboBox extends GridPane {
        @FXML
        private ComboBox<String> comboBox;
        public ListComboBox() {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("widget/ListComboBox.fxml"));
            fxmlLoader.setRoot(this);
            fxmlLoader.setController(this);
            try {
                fxmlLoader.load();
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }
        }
    }

RoundedButton.java

    public class RoundedButton extends Button {
        public RoundedButton() {
            super();
            this.setStyle("-fx-background-radius: 10; -fx-background-color: #eee8aa; -fx-text-fill: #8b4513; -fx-font-size: 3em; ");
        }
    }

Я надеюсь получить пользовательский интерфейс для загрузки с настраиваемым полем со списком и закругленной кнопкой, но UIHomePage.fxml не может загрузить ListComboBox (настраиваемое поле со списком), и я продолжаю получать следующее сообщение об ошибке

    javafx.fxml.LoadException: 
/home/gangs/Programming/workspace/Java/TestProject/bin/ui/UIHomePage.fxml:7
        at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
        at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
        at application.Main.start(Main.java:18)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
        at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139)
        at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.IllegalStateException: Location is not set.
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
        at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
        at widget.ListComboBox.<init>(ListComboBox.java:25)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
        at javafx.fxml.FXMLLoader$InstanceDeclarationElement.constructValue(FXMLLoader.java:1009)
        at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:746)
        at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
        at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
        ... 17 more

Одно из известных мне решений будет работать, если я поместу все файлы fxml в папку src, но это затруднит управление проектом по мере его роста. Я хочу сохранить эту структуру разделения кода Java и файла fxml в отдельных папках, чтобы в будущем обслуживание кода было проще.

Может кто-нибудь помочь мне понять, что я здесь пропустил?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...