JavaFX 8 loading multiple fxml files into borderpane

前端 未结 1 1379
野趣味
野趣味 2020-12-02 02:50

Given the following code:

public class Main extends Application {

private BorderPane rootLayout;
private VBox toolbarLayout;

private URL path;

publ         


        
相关标签:
1条回答
  • 2020-12-02 02:58

    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.

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

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

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

    0 讨论(0)
提交回复
热议问题