初始化/ FXML注入期间的Nullpointer异常未按预期工作 [英] Nullpointer Exception during initialize / FXML injection not working as expected

查看:107
本文介绍了初始化/ FXML注入期间的Nullpointer异常未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到我的一个控制器类中有一种奇怪的行为。其中一个组件未初始化。

I noticed a weird behaviour in one of my controller classes. One of the components is not getting initialized.

这是fxml:

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="500.0" prefWidth="712.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="modulartoolkit.ConfigWindowController">
    <children>
        <Label layoutX="14.0" layoutY="12.0" text="Processes:" />
        <Button fx:id="newProcessButton" layoutX="324.0" layoutY="82.0" mnemonicParsing="false" onAction="#handleNewProcessButtonAction" prefHeight="25.0" prefWidth="51.0" text="New" />
        <Button fx:id="editProcessButton" layoutX="324.0" layoutY="118.0" mnemonicParsing="false" onAction="#handleEditProcessButtonAction" prefHeight="25.0" prefWidth="51.0" text="Edit" />
        <Button fx:id="deleteProcessButton" layoutX="324.0" layoutY="154.0" mnemonicParsing="false" onAction="#handleDeleteProcessButtonAction" text="Delete" />
        <ListView fx:id="processListView" layoutX="14.0" layoutY="30.0" prefHeight="200.0" prefWidth="295.0" />
        <Label layoutX="14.0" layoutY="250.0" text="Available Modules:" />
        <Label layoutX="400.0" layoutY="250.0" text="Configured Modules:" />
        <ListView layoutX="397.0" layoutY="266.0" prefHeight="200.0" prefWidth="295.0" />
        <TreeView layoutX="14.0" layoutY="266.0" prefHeight="200.0" prefWidth="295.0" />
    </children>
</AnchorPane>

这将是控制器:

public class ConfigWindowController implements Initializable {

    private Database database;
    private final ObservableList processListData = FXCollections.observableArrayList();

    @FXML
    private Button newProcessButton;
    private Button editProcessButton;
    private Button deleteProcessButton;
    private ListView<String> processListView;

    /**
     * Initializes the controller class.
     *
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.database = Database.getInstance();
        processListView.setItems(processListData);
    }

    @FXML
    private void handleNewProcessButtonAction(ActionEvent event) {
        System.out.println("new Process");
    }

    @FXML
    private void handleEditProcessButtonAction(ActionEvent event) {
        System.out.println("EDIT!");
    }

    @FXML
    private void handleDeleteProcessButtonAction(ActionEvent event) {
        System.out.println("DELETE!");
    }

}

启动应用程序后,我得到 NullPointerException ,因为 ListView 为空。
我可以通过在 ListView 中添加@FXML注释来修复它:

Once I start the application, I get a NullPointerException because the ListView is null. I can fix it by adding an @FXML annotation to the ListView:

@FXML
private Button newProcessButton;
private Button editProcessButton;
private Button deleteProcessButton;
@FXML
private ListView<String> processListView;

如果我移动 ListView 它也有效到声明的顶部。在每种情况下,所有按钮都会被初始化。

It also works if I move the ListView to the top of the declaration. All the buttons are getting initialized in each case.

有人知道为什么会这样吗?我认为注释只需要在声明的开头。或者是否必须为每种类型的组件输入?

Does anybody know why this is happening? I thought the annotation only needs to be at the start of the declarations. Or does it have to be entered for each type of component?

推荐答案

实际上最后两个按钮没有启动,所以它们必须是 null 。但是,fxml文件中定义的按钮是实例化的,并且具有 onAction 属性,这些属性设置为控制器类中定义的@FXML注释。因此,单击这些按钮将起作用并按预期触发事件操作处理程序。

Actually the last two buttons are not initiated, so they must be null. However the buttons defined in the fxml file are instantiated and have onAction properties set with the ones defined in the controller class which also have @FXML annotated. Thus clicking on these buttons will work and triggers the event action handlers as expected.

@FXML注释要求FXMLLoader实例化带注释的节点并将其链接到定义的节点具有相应 fx:id 的fxml文件。因此,如果节点未使用@FXML注释并且未明确启动,则它为null。这就是注释在Java语言中的工作方式。您可以通过检查最后两个按钮的空值来确认这一点。

@FXML annotation obligates the FXMLLoader to instantiate the annotated node and link it to the node defined in fxml file with the respective fx:id. So if the node is not annotated with @FXML and not initiated explicitly then it is null. This is how the annotations work in Java language. You can confirm this by checking the last two buttons for nullness.

因此,每个控件/节点都应单独注释:

So, every control/node should be annotated separately:

@FXML
private Button newProcessButton;

@FXML
private Button editProcessButton;

@FXML
private ListView<String> processListView;

或合并如下:

@FXML
private Button newProcessButton, editProcessButton;

@FXML
private ListView<String> processListView;

这篇关于初始化/ FXML注入期间的Nullpointer异常未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆