我在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文件放在单独文件夹下的结构,以便将来代码维护更加容易。
有人可以帮助我了解我在这里错过的是什么吗?