【发布时间】:2015-10-15 17:53:15
【问题描述】:
给定以下代码:
公共类主扩展应用程序{
private BorderPane rootLayout;
private VBox toolbarLayout;
private URL path;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
FXMLLoader loader = new FXMLLoader();
// Root View
path = getClass().getResource("mainLayout.fxml");
try {
loader.setLocation(path);
rootLayout = (BorderPane) loader.load();
} catch (IOException e){
System.out.println("Not found: " + path);
e.printStackTrace();
}
// Toolbar View
path = getClass().getResource("toolbar/toolbarView.fxml");
try {
toolbarLayout = (VBox) loader.load();
} catch (IOException e){
System.out.println("Not found: " + path);
e.printStackTrace();
}
rootLayout.getChildren().add(toolbarLayout);
Scene scene = new Scene(rootLayout);
stage.setScene(scene);
stage.show();
}
如果我注释掉第二个 fxml 'try' rootLayout 加载正常。如果我注释掉边框并将工具栏视图设置为主视图,它也可以正常工作。 但是如果我尝试将toolbarView加载到rootLayout中,rootLayout加载正常,但是toolbarView会抛出异常:
javafx.fxml.LoadException: Root value already specified.
显然我不太了解 fxml 加载过程,所以有人可以解释一下吗?为什么它认为我在尝试再次设置根目录?
为了完整起见,这里是toolbarView.fxml:
<VBox fx:id="idToolbar" alignment="TOP_CENTER" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="100.0" spacing="20.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" text="Button" />
<Button mnemonicParsing="false" text="Button" />
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<padding>
<Insets top="20.0" />
</padding>
</VBox>
【问题讨论】:
-
为了完整起见,这里是 fxml:
-
您不能将单个
FXMLLoader重复用于像这样的不同 FXML 文件。只需为您要加载的每个文件创建一个新的FXMLLoader。 -
这行得通 - 谢谢。但是为什么加载器类不能被重用呢?我认为通过重置位置(loader.setLocation),它只会加载一个新的 fxml,我在第二个“加载”之前有该行,但在失败时将其取出)。每个 FXML 加载器是否保留对其加载的 fxml 文件的内存引用?
-
简而言之,因为这是他们编写 API 的方式。我怀疑做出这个决定是因为每个加载过程都依赖于多个相互依赖的属性(位置、资源、控制器),所以如果你可以重用加载器,很容易引入难以跟踪的错误。
-
我错过了最后一部分:是的,加载器保留了对
root属性中加载的结构的引用。