且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JavaFX 8 将多个 fxml 文件加载到边界窗格中

更新时间:2022-02-15 02:15:57

root 属性包含对 FXML 文件指定结构的引用;即到由 FXML 文件的根元素创建的对象.假设您没有使用 "动态根"()模式,根将作为load过程的一部分设置到根元素对应的对象的 FXML.如果在这个阶段它不是 null(即如果它已经被设置),那么你会得到一个异常.controller 属性也有类似的情况:如果 FXML 文件指定了 fx:controller 属性,则控制器将被设置为 load() 的一部分 过程;如果不是null,则抛出异常.

The root property contains a reference to the structure specified by the FXML file; i.e. to the object created by the root element of the FXML file. Assuming you are not using the "dynamic root" (<fx:root>) pattern, the root will be set as part of the load process to the object corresponding to the root element of the FXML. If it is not null at this stage (i.e. if it has already been set), then you will get an exception. A similar thing is true for the controller property: if the FXML file specifies an fx:controller attribute, the controller will be set as part of the load() process; if it is not null, an exception is thrown.

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

The FXMLLoader is really only designed to be used once, as you have many interdependent properties which are typically set as part of the load process: root, location, controller, resources, and elements of the namespace. So you should really create a new FXMLLoader for each FXML file you want to load:

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:

It may be possible to reuse an FXMLLoader by carefully unsetting anything that has been set as part of the previous load process:

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

但这确实不是预期的用途,并且可能对 FXMLLoader 实现的未来更改不健壮.

but this is really not the intended usage, and may not be robust to future changes to the FXMLLoader implementation.