Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
初始化JavaFX视图时的空指针_Java_Javafx - Fatal编程技术网

初始化JavaFX视图时的空指针

初始化JavaFX视图时的空指针,java,javafx,Java,Javafx,我正在使用JavaFX显示游戏中的视图 在调用我的MainApp类中的方法时,将加载该视图: public class MainApp extends Application { //fields public MainApp() { this.game = new Game(); } //lots of other methods public void showGameView() { try {

我正在使用JavaFX显示游戏中的视图

在调用我的
MainApp
类中的方法时,将加载该视图:

public class MainApp extends Application {

    //fields

    public MainApp() {
        this.game = new Game();
    }

    //lots of other methods

    public void showGameView() {
        try {
            System.out.println(game.getPlayer().getCurrentRoom());
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/GameView.fxml"));
            AnchorPane GameView = (AnchorPane) loader.load();
            rootLayout.setCenter(GameView);
            GameViewController controller = loader.getController();
            controller.setMainApp(this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Game getGame() {
        return game;
    }
游戏
对象存储一些信息和东西。控制器的外观如下所示:

public class GameViewController {

    private MainApp mainApp;

    @FXML
    public void initialize() {
        mainApp.getGame().  ... //do something else
    }

    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;
    }

我一直都是这样做的。当控制器加载时,会在控制器中设置
MainApp
对象,我可以使用它。但是现在,当调用任何
mainApp.get…
时,我会得到一个空指针。字段
mainApp
为空。我真的不知道这里的交易是什么,因为正如我所说的,它在其他项目中也是这样工作的。

控制器类的
初始化
方法在
fxmloader.load
方法调用的末尾被调用,即在调用之前

controller.setMainApp(this);
这意味着此时,
mainApp
字段仍然包含
null


您必须将代码取消引用
mainApp
initialize
方法移动到
setMainApp
方法,自己用initialized
mainApp
属性创建控制器实例,并在加载之前将其传递给
fxmloader
(需要删除
fx:controller
属性)或者使用控制器工厂初始化控制器实例(这可能是最复杂的选项)。

实际上只是fabian答案的扩展。我同意您应该自己创建控制器实例(如他所说,删除FXML中的
fx:controller
)。它允许您将内容声明为
final
,否则您将无法这样做,并且避免在公共API中加载您不需要的setter

您可能会将大量
初始化
代码移动到构造函数中。如果直接修改任何JavaFX小部件,我通常只将代码放入
initialise

它看起来像这样:

public void showGameView() {
    try {
        System.out.println(game.getPlayer().getCurrentRoom());
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(MainApp.class.getResource("view/GameView.fxml"));
        loader.setController(new GameViewController(this));
        AnchorPane GameView = (AnchorPane) loader.load();
        rootLayout.setCenter(GameView);

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


确定,因此该字段为空,因为该字段是在调用
initialize()
之后设置的。我想在
setMainApp()
中调用另一个
init()
方法有点不干净,但我想我必须这样做。感谢you@Master1114通常的方法是从
setMainApp(…)
方法调用
mainApp.getGame(…)
etc;但是如果你想要一个额外的
init()
方法,没有什么可以阻止你这么做。这看起来是一个非常好而且简单的解决方案。我猜它的风格比我最初在其他答案的评论中所想的更简洁。也谢谢你!
public class GameViewController {

    private final MainApp mainApp;

    public GameViewController(MainApp mainApp)
    {
        this.mainApp = mainApp;
    }

    @FXML
    public void initialize() {
        mainApp.getGame().  ... //do something else
    }