JavaFX跨控制器调用addTab方法时TabPane为空报空指针如何解决
问题根因
你在NewProjectController的addNewProject方法中手动创建了全新的WorkspaceController实例,这个手动new出来的实例并没有经过FXMLLoader的初始化流程,FXML里定义的TabPane控件没有被注入到这个新实例中,所以调用addTab()时this.TabPane为null,抛出空指针异常。
而你在WorkspaceController内部调用方法时,用的是FXMLLoader加载FXML时生成的已完成控件注入的实例,所以可以正常运行。
修复步骤
- 改造
NewProjectController,新增成员变量接收当前已初始化的WorkspaceController实例,修改构造方法:
public class NewProjectController { @FXML private TextField NewProjectTextField; @FXML private Button okButton; @FXML private Button cancelButton; private Stage stage; private Stage parentStage; public UserModel model; public User user; // 新增成员变量存储已初始化的WorkspaceController实例 private WorkspaceController workspaceController; // 构造方法新增WorkspaceController参数 public NewProjectController(Stage parentStage, UserModel model, WorkspaceController workspaceController) { this.stage = new Stage(); this.parentStage = parentStage; this.model = model; this.workspaceController = workspaceController; } // 其余原有代码保留不变
- 修改
NewProjectController的addNewProject方法,不要手动new WorkspaceController,直接用传入的实例调用方法:
@FXML public void addNewProject(ActionEvent event){ // 删掉原来手动new WorkspaceController的代码 workspaceController.addTab(); // 可选:新增关闭当前新建项目窗口的逻辑 stage.close(); }
- 修改
WorkspaceController中初始化NewProjectController的代码,把当前实例(this)传入构造方法:
public void newProjectOnAction(ActionEvent event) throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("/resources/View/NewProjectView.fxml")); Callback<Class<?>, Object> controllerFactory = param -> { // 构造方法新增传入当前WorkspaceController实例(this) return new NewProjectController(stage, model, this); }; loader.setControllerFactory(controllerFactory); Pane root = loader.load(); NewProjectController newProjectController = loader.getController(); newProjectController.showStage(root); }
额外建议
Java编码规范中成员变量名建议使用小驼峰命名,你当前的TabPane变量名首字母大写,容易和类名混淆,建议修改为tabPane,同步修改FXML文件中的fx:id对应值即可。
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

