简体   繁体   中英

JavaFX+MVC. Change center in BorderPane and NullPointerException

I have 2 controllers and 3 FXML-files.
1. Controllers:
MainController.java
In this controller i am create Stage and Scene with BorderPane. In center of BorderPane i want to change layouts(GridPane, HBox etc)

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
In the SecondController i want to change Center of borderPane MainController with help radioButton.

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:
0.BaseView.fxml - base view
1. CenterView1.fxml (by default) - it's BorderPane in the center of Base View
2. CenterView2.fxml - it's DataGrid in the center of Base View

When i click on rbSecond i see NullPointerException in mainController.getDefaultNormsLayout() . 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.
Thanks!

Answer from my comment:

The nullpointer occures, because the controller is not initialized before the load operation of the FXMLLoader. This will create another instance of the MainController class. This will not be the same instance as the initial one, if the default JavaFX is not overwritten. See the setControllerFactory method of the FXMLLoader class. Keep in mind that it is important to not reuse the FXMLLoader class.

The following should ensure that mainController is not null anymore.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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