首页 文章

初始化/ FXML注入期间的Nullpointer异常未按预期工作

提问于
浏览
0

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

这是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注释来修复它:

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

如果我将 ListView 移动到声明的顶部,它也可以工作 . 在每种情况下,所有按钮都会被初始化 .

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

1 回答

  • 0

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

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

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

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

    或者如下组合:

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

相关问题