手动添加控制器时FXML对象上的nullPointerException

时间:2017-04-02 12:04:00

标签: java javafx nullpointerexception fxml

我正在制作一个应用程序,其中PuzzleBlocks正在5x5矩形的网格中构建。我已经不再在.fxml文件中声明fx:controller而是在main中执行此操作:

@Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader baseViewLoader = new FXMLLoader(getClass().getResource("Views/BaseView.fxml"));
        baseViewLoader.setLocation(getClass().getResource("Views/BaseView.fxml"));
        baseViewLoader.setController(new DockViewController());
        Parent root = baseViewLoader.load();

        FXMLLoader dockLoader = new FXMLLoader(getClass().getResource("Views/DockView.fxml"));
        dockLoader.setLocation(getClass().getResource("Views/DockView.fxml"));
        dockLoader.setController(new DockViewController());
        Parent dockView = dockLoader.load();

        primaryStage.setResizable(false);
        primaryStage.sizeToScene();

        primaryStage.setTitle("Tiles 2059275");

        Scene gameScene = new Scene(root);

        primaryStage.setScene(gameScene);

        primaryStage.show();

        new GameController();
    }

现在之前,当通过.fxml文件声明Controller来完成它时,我的DockViewController初始化中的这段代码将正常工作:

@FXML
    StackPane dockStackPane;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                tile1 = createSquare(Color.GREY);
                tile2 = createSquare(Color.GREY);
                tile3 = createSquare(Color.GREY);

                tile1.setTranslateX(32 * (i) - 176);
                tile1.setTranslateY(32 * (j) - 48);

                tile2.setTranslateX(32 * (i) - 16);
                tile2.setTranslateY(32 * (j) - 48);

                tile3.setTranslateX(32 * (i) + 144);
                tile3.setTranslateY(32 * (j) - 48);

                dockStackPane.getChildren().add(tile1);
                dockStackPane.getChildren().add(tile2);
                dockStackPane.getChildren().add(tile3);

                puzzleBlock1.add(tile1);
                puzzleBlock2.add(tile2);
                puzzleBlock3.add(tile3);
            }
        }
        System.out.println("Ini test");
    }

错误发生在dockStackPane.getChildren().add(tile1);,因为dockStackPane为null。如果我删除我在Main中手动添加控制器并返回在FXML文件中添加带有fx:controller的控制器,它可以正常工作。但后来我没有引用我的控制器。

DockView.fxml

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

<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="128.0" prefWidth="384.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <StackPane fx:id="dockStackPane" prefHeight="128.0" prefWidth="384.0" />
   </children>
</Pane>

DockView包含在BaseView

1 个答案:

答案 0 :(得分:0)

感谢对我的问题的评论我能够解决的问题是在我的BaseView.fxml中为include添加一个fx:id:

 <fx:include fx:id="includedDockView" source="DockView.fxml" />

确保include元素的fx:controller设置为:

<Pane fx:id="dockPane" fx:controller="tiles.Controllers.DockViewController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="128.0" prefWidth="384.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">

然后在BaseViewController中你可以这样做:

@FXML
    private DockViewController includedDockViewController;

    public DockViewController getDockViewController() {
        return includedDockViewController;
    }

在主体中你可以传递BaseView:

public void start(Stage primaryStage) throws Exception {
    FXMLLoader baseViewLoader = new FXMLLoader(getClass().getResource("Views/BaseView.fxml"));
    baseViewLoader.setLocation(getClass().getResource("Views/BaseView.fxml"));
    baseViewLoader.setController(new BaseViewController());
    Parent root = baseViewLoader.load();

    primaryStage.setResizable(false);
    primaryStage.sizeToScene();

    primaryStage.setTitle("Tiles 2059275");

    Scene gameScene = new Scene(root);

    primaryStage.setScene(gameScene);

    primaryStage.show();

    new GameController(baseViewLoader);
}