You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX多控制器通信空指针异常求助:控制器初始化失败

JavaFX控制器中转通信空指针问题排查

我在学习JavaFX控制器间通信时,尝试通过MainController实现KontrolerA与KontrolerB的中转通信,排查两天仍未解决,运行时报错如下:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
    at java.base/java.lang.reflect.Method.invoke(Method.java:565)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:470)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:370)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:565)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1184)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:899)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$0(LauncherImpl.java:202)
    at java.base/java.lang.Thread.run(Thread.java:1516)
Caused by: javafx.fxml.LoadException: 
/C:/Users/user/IdeaProjects/SharedModel2/target/classes/com/example/sharedmodel2/hello-view.fxml

    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2692)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2670)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2533)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3304)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3264)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3235)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3211)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3191)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3186)
    at com.example.sharedmodel2/com.example.sharedmodel2.Aplikacija.start(Aplikacija.java:18)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$4(LauncherImpl.java:845)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$0(PlatformImpl.java:449)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$0(PlatformImpl.java:424)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$0(WinApplication.java:173)
    ... 1 more
Caused by: java.lang.NullPointerException: Cannot invoke "com.example.sharedmodel2.KontrolerA.init(com.example.sharedmodel2.MainController)" because "this.kontrolerA" is null
    at com.example.sharedmodel2/com.example.sharedmodel2.MainController.initialize(MainController.java:17)
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2640)
    ... 15 more
Exception running application com.example.sharedmodel2.Aplikacija

三个FXML对应控制器代码如下:
KontrolerA代码:

public class KontrolerA{

    private MainController main;

    @FXML TextField unosPolje;

    @FXML public void setButton(ActionEvent event){
        main.labelaSetText(unosPolje.getText());
    }

    public void init(MainController mc){
        this.main = mc;
    }

}

KontrolerB代码:

public class KontrolerB {

    private MainController main;

    @FXML public Label labela;

    public void init(MainController mc){
        this.main = mc;
    }

}

MainController代码:

public class MainController implements Initializable {

    @FXML KontrolerA kontrolerA;
    @FXML KontrolerB kontrolerB;

    @Override
    @FXML public void initialize(URL location, ResourceBundle resources) {
        kontrolerA.init(this);
        kontrolerB.init(this);
    }

    @FXML public void labelaSetText(String txt){
        kontrolerB.labela.setText(txt);
    }


}

主FXML文件配置:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/26" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE">
         <tabs>
            <Tab text="Untitled Tab 1">
               <content>
                  <fx:include fx:id="a" source="A.fxml" />
               </content>
            </Tab>
            <Tab text="Untitled Tab 2">
               <content>
                  <fx:include fx:id="b" source="B.fxml" />
               </content>
            </Tab>
         </tabs>
      </TabPane>
   </children>
</AnchorPane>

为何会出现‘无法调用com.example.sharedmodel2.KontrolerA.init方法,因this.kontrolerA为空’,以及后续‘this.main为空无法调用labelaSetText’的问题?


问题原因分析

  • 第一个空指针(kontrolerA为null):FXML加载子控制器时,遵循**fx:id + "Controller"**的命名规则进行注入。你主FXML里fx:id="a",对应的控制器字段名应为aController,而非kontrolerA,导致MainController中的kontrolerA未被FXMLLoader注入,初始化时调用init()触发空指针。
  • 后续main为空:由于KontrolerA的init()未被成功调用,其main字段始终为null,点击按钮调用labelaSetText()时自然报错。

修复方案

步骤1:修正MainController的字段命名

将MainController中的控制器字段名改为与fx:id对应的规则命名:

public class MainController implements Initializable {

    @FXML KontrolerA aController; // 对应fx:id="a"
    @FXML KontrolerB bController; // 对应fx:id="b"

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        aController.init(this);
        bController.init(this);
    }

    public void labelaSetText(String txt){
        bController.labela.setText(txt);
    }
}

注意:initialize方法无需添加@FXML注解,它是Initializable接口的实现方法,FXMLLoader会自动调用。

步骤2:验证子FXML的控制器配置

检查A.fxml和B.fxml的根节点是否正确指定了控制器:

  • A.fxml根节点需添加:fx:controller="com.example.sharedmodel2.KontrolerA"
  • B.fxml根节点需添加:fx:controller="com.example.sharedmodel2.KontrolerB"
    否则FXMLLoader无法实例化对应控制器,依然会导致空指针。

步骤3:验证通信逻辑

修复后,点击KontrolerA的按钮时,会调用MainController的labelaSetText方法,进而修改KontrolerB中labela的文本,完成中转通信。

内容的提问来源于stack exchange,提问作者Nikola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 06:44:57