如何在Eclipse中修复JavaFX项目的“ java.lang.IllegalStateException:未设置位置”

时间:2019-05-31 02:37:05

标签: java eclipse javafx

我在eclipse中创建了一个JavaFX项目,其中将Java代码保留在src文件夹下,将fxml文件保留在resources文件夹下。有一些UI组件没有相应的fxml文件,例如自定义按钮。

当我尝试将此类组件导入fxml文件时,出现以下错误     原因:java.lang.IllegalStateException:未设置位置。

我查看了许多与“ java.lang.IllegalStateException:未设置位置”错误有关的问题,但找不到与我同样的问题。

为简单起见,我用一个较小的项目重现了该错误,其中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资源。

我面临的问题是,当我尝试加载资源/ui/UIHomePage.fxml时,由于无法找到src / widget / ComboBox,它无法弄清ListComboBox的位置。

我也将src和resources文件夹都添加为Java Build Path中的Source。

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; ");
        }
    }

我希望通过自定义组合框和圆形按钮加载UI,但是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文件放在单独文件夹下的结构,以便将来代码维护更加容易。

有人可以帮助我了解我在这里错过的是什么吗?

0 个答案:

没有答案