初始化/ FXML注入期间的Nullpointer异常未按预期工作(Nullpointer Exception during initialize / FXML injection not worki

编程入门 行业动态 更新时间:2024-10-17 09:49:04
初始化/ FXML注入期间的Nullpointer异常未按预期工作(Nullpointer Exception during initialize / FXML injection not working as expected)

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

这是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为null。 我可以通过向ListView添加@FXML注释来修复它:

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

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

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

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

This is the 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>

And this would be the controller:

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!"); } }

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;

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属性设置为控制器类中定义的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;

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 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;

Or as combined like:

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

更多推荐

本文发布于:2023-08-07 07:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1462707.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:初始化   未按   异常   工作   Nullpointer

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!