gpt4 book ai didi

JavaFX 8 将多个 fxml 文件加载到 borderpane

转载 作者:行者123 更新时间:2023-12-04 00:21:39 25 4
gpt4 key购买 nike

给定以下代码:

公共(public)类主要扩展应用程序{

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“尝试”,则 rootLayout 加载正常。如果我注释掉 borderpane 并将 toolbarView 设置为主视图,它也可以正常工作。但是如果我尝试将 toolbarView 加载到 rootLayout 中,rootLayout 加载正常,但 toolbarView 抛出异常:

javafx.fxml.LoadException: Root value already specified.

显然我不太了解 fxml 加载过程,所以有人可以对此有所了解吗?为什么它认为我正在尝试再次设置 root?

为了完整起见,这里是 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>

最佳答案

root属性包含对 FXML 文件指定的结构的引用;即由 FXML 文件的根元素创建的对象。假设您没有使用 "dynamic root" ( <fx:root> ) pattern , root 将被设置为 load 的一部分处理对应于 FXML 根元素的对象。如果不是 null在这个阶段(即如果它已经被设置),那么你会得到一个异常(exception)。 controller 也是如此。属性:如果 FXML 文件指定 fx:controller属性, Controller 将被设置为 load() 的一部分过程;如果不是 null , 抛出异常。

FXMLLoader实际上只设计为使用一次,因为您有许多相互依赖的属性,这些属性通常设置为加载过程的一部分:root , location , controller , resources ,以及 namespace 的元素.所以你真的应该创建一个新的 FXMLLoader对于要加载的每个 FXML 文件:

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

loader = new FXMLLoader();

path = getClass().getResource("toolbar/toolbarView.fxml");
try {

// note you omitted this line:
loader.setLocation(path);

toolbarLayout = (VBox) loader.load();
} catch (IOException e){
System.out.println("Not found: " + path);
e.printStackTrace();
}

rootLayout.getChildren().add(toolbarLayout);

重用 FXMLLoader 是可能的通过小心地取消设置作为先前加载过程的一部分设置的任何内容:

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

loader.setRoot(null);
loader.setController(null);
loader.setResources(null);
loader.getNamespace().clear();

// Toolbar View
path = getClass().getResource("toolbar/toolbarView.fxml");

try {

// note you omitted this line:
loader.setLocation(path);

toolbarLayout = (VBox) loader.load();
} catch (IOException e){
System.out.println("Not found: " + path);
e.printStackTrace();
}

rootLayout.getChildren().add(toolbarLayout);

但这确实不是预期的用途,并且可能无法适应 future 对 FXMLLoader 的更改。执行。

关于JavaFX 8 将多个 fxml 文件加载到 borderpane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31621017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com