简体   繁体   English

JavaFX + MVC。 更改BorderPane和NullPointerException中的中心

[英]JavaFX+MVC. Change center in BorderPane and NullPointerException

I have 2 controllers and 3 FXML-files. 我有2个控制器和3个FXML文件。
1. Controllers: 1.控制器:
MainController.java MainController.java
In this controller i am create Stage and Scene with BorderPane. 在此控制器中,我使用BorderPane创建舞台和场景。 In center of BorderPane i want to change layouts(GridPane, HBox etc) 在BorderPane的中心,我想更改布局(GridPane,HBox等)

public class MainController {

    //Main BorderPane
    private BorderPane borderPane;

    @FXML
    private void initialize() {
       try {

          FXMLLoader  mainLoaderFXML = new FXMLLoader();
          mainLoaderFXML.setLocation(getClass().getResource("BaseView.fxml"));
          borderPane = (BorderPane) mainLoaderFXML.load();

          Stage mainStage = new Stage();
          mainStage.setTitle("Border Pane");

          Scene mainScene = new Scene(borderPane);
          mainStage.setScene(mainScene);

          FXMLLoader loader = new FXMLLoader();
          loader.setLocation(getClass().getResource("CenterView1.fxml"));

          //BorderPane in CenterView1.fxml          
          BorderPane centerView1 = (BorderPane) loader.load();

          borderPane.setCenter(centerView1);

          mainStage.show();


       } catch (IOException e) {
          e.printStackTrace();
       }

    }

    //Get BorderPane
    public BorderPane getBorderPane() {
         return this.borderPane;
    }

}

SecondController.java SecondController.java
In the SecondController i want to change Center of borderPane MainController with help radioButton. 在SecondController中,我想使用帮助radioButton更改borderPane MainController的中心。

public class SecondController {
    @FXML
    private ToggleGroup radioButtons;

    @FXML
    private void initialize() {

        radioButtons.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
            public void changed(ObservableValue<? extends Toggle> ov,
                Toggle old_toggle, Toggle new_toggle) {
                if (radioButtons.getSelectedToggle() != null) {
                    RadioButton chk = (RadioButton)new_toggle.getToggleGroup().getSelectedToggle(); 

                    switch(chk.getText()){
                        case "rbFirst": 
                            System.out.println("Default View CenterView1"); 
                            break;
                        case "rbSecond": 

                            FXMLLoader  mainLoaderFXML = new FXMLLoader();
                                mainLoaderFXML.setLocation(getClass().getResource("BaseView.fxml"));

                                MainController mainController = (MainController)mainLoaderFXML.getController();

                                //And now i want to change new FXML-file into center, but i have a NULLPointerException
                                System.out.println(mainController.getDefaultNormsLayout().setCenter("CenterView2"));
                            break;
                    }
                }
            }
        });
    }
}


2. FXML-file: 2. FXML文件:
0.BaseView.fxml - base view 0.BaseView.fxml-基本视图
1. CenterView1.fxml (by default) - it's BorderPane in the center of Base View 1. CenterView1.fxml (默认情况下)-它是Base View中心的BorderPane
2. CenterView2.fxml - it's DataGrid in the center of Base View 2. CenterView2.fxml-它是基本视图中心的DataGrid

When i click on rbSecond i see NullPointerException in mainController.getDefaultNormsLayout() . 当我单击rbSecond时,我在mainController.getDefaultNormsLayout()中看到NullPointerException I know what is it, but i don't know hot to fix it. 我知道这是什么,但我不知道要修复它。 I am use JavaFX class controller scene reference , enter link description here etc but i don't known how to it apply for my task. 我正在使用JavaFX类控制器场景参考在此处输入链接描述等,但我不知道如何将其应用于我的任务。
Thanks! 谢谢!

Answer from my comment: 我的评论回答:

The nullpointer occures, because the controller is not initialized before the load operation of the FXMLLoader. 出现空指针是因为在FXMLLoader的加载操作之前未初始化控制器。 This will create another instance of the MainController class. 这将创建MainController类的另一个实例。 This will not be the same instance as the initial one, if the default JavaFX is not overwritten. 如果未覆盖默认的JavaFX,则此实例将与初始实例不同。 See the setControllerFactory method of the FXMLLoader class. 请参见FXMLLoader类的setControllerFactory方法。 Keep in mind that it is important to not reuse the FXMLLoader class. 请记住,不要重用FXMLLoader类,这一点很重要。

The following should ensure that mainController is not null anymore. 以下内容应确保mainController不再为null。

FXMLLoader  mainLoaderFXML = new FXMLLoader(); 
mainLoaderFXML.setLocation(getClass().getResource("BaseView.fxml"));
mainLoaderFXML.load();
MainController mainController =  (MainController)mainLoaderFXML.getController();

Singleton Controller 单例控制器

Use singleton mechanic of your choice and get the instance. 使用您选择的单例机制并获取实例。 If you want to control the creation of a controller classe use. 如果要控制控制器类的创建,请使用。

mainLoaderFxml.setControllerFactory(new Callback() {
     public Object call(Class<?> clazz) {
          return instance of your class;
     }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM