我有 2 个 Controller 和 3 个 FXML 文件。
1. Controller :
MainController.java
在此 Controller 中,我使用 BorderPane 创建舞台和场景。在 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 中,我想借助 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 文件:
0.BaseView.fxml - 基础 View
1. CenterView1.fxml(默认情况下) - 它是基本 View 中心的 BorderPane
2. CenterView2.fxml - 它是位于基本 View 中心的 DataGrid
当我点击rbSecond时,我在mainController.getDefaultNormsLayout()中看到NullPointerException。我知道它是什么,但我不知道如何修复它。我正在使用JavaFX class controller scene reference , enter link description here等等,但我不知道如何应用它来完成我的任务。
谢谢!
最佳答案
我的评论的答案:
出现空指针是因为在FXMLLoader加载操作之前 Controller 没有初始化。这将创建 MainController 类的另一个实例。如果默认的 JavaFX 没有被覆盖,这将不是与第一个实例相同的实例。 请参阅 FXMLLoader 类的 setControllerFactory 方法。请记住,不要重用 FXMLLoader 类,这一点很重要。
以下内容应确保 mainController 不再为 null。
FXMLLoader mainLoaderFXML = new FXMLLoader();
mainLoaderFXML.setLocation(getClass().getResource("BaseView.fxml"));
mainLoaderFXML.load();
MainController mainController = (MainController)mainLoaderFXML.getController();
单例 Controller
使用您选择的单例机制并获取实例。如果您想控制 Controller 类的创建,请使用。
mainLoaderFxml.setControllerFactory(new Callback() {
public Object call(Class<?> clazz) {
return instance of your class;
}
}
关于JavaFX+MVC。 BorderPane 和 NullPointerException 中的更改中心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35817911/