[英]FXML variable reference is null
So I'm learning how to use FXMl and I have run into yet another problem with getting a reference to an object by fx:id at runtime, I get a null pointer exception with the following code. 因此,我正在学习如何使用FXMl,并且在运行时通过fx:id获取对对象的引用遇到了另一个问题,使用以下代码会得到空指针异常。
<TableView fx:id="productTable" layoutX="92.0" layoutY="319.0" prefHeight="97.0" prefWidth="363.0" GridPane.columnIndex="7" GridPane.columnSpan="5" GridPane.rowIndex="3" GridPane.rowSpan="2">
<columns>
<TableColumn prefWidth="98.0" text="Product ID" fx:id="productID"/>
<TableColumn prefWidth="110.0" text="Product Name" fx:id="productName"/>
<TableColumn prefWidth="131.0" text="Inventory Level" fx:id="productInventoryLevel"/>
<TableColumn prefWidth="128.0" text="Price per Unit" fx:id="productPrice"/>
</columns>
</TableView>
//Controller.java
@FXML private TableView<Product> productTable;
@FXML private TableColumn<Product, String> productID;
@FXML private TableColumn<Product, String> productPrice;
@FXML private TableColumn<Product, String> productName;
@FXML private TableColumn<Product, String> productInventoryLevel;
//Product properties declared the same as https://docs.oracle.com/javafx/2/ui_controls/table-view.htm#
private ObservableList<Product> productData = FXCollections.observableArrayList(
new Product(0, "Wheel", 100.99, 4, 0, 1),
new Product(1, "Seat", 50.0, 4, 0, 1));
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
System.out.println("Product ID factories");
productID.setCellValueFactory(new PropertyValueFactory<Product, String>("productID"));
productPrice.setCellValueFactory(new PropertyValueFactory<Product, String>("productPrice"));
productInventoryLevel.setCellValueFactory(new PropertyValueFactory<Product, String>("productInventoryLevel"));
productName.setCellValueFactory(new PropertyValueFactory<Product, String>("productName"));
productTable.setItems(productData);
System.out.println("Set items");
}
As you can see I declare the @FXML
tag, then the variable by fx:id
and right after my first print statement I get a runtime nullpointer exception on the productID
如您所见,我声明了
@FXML
标记,然后声明了fx:id
变量,并在第一个打印语句之后立即在productID
上获得了运行时nullpointer异常
EDIT: The above code currently runs without error but will only populate the "productID" section of my table. 编辑:上面的代码当前运行没有错误,但只会填充我的表的“ productID”部分。
Firstly, it's not sure what the UI
class extends. 首先,不确定
UI
类的扩展范围。 It does look like it extended from Application
, and is the starting class of the whole application. 它看起来确实是从
Application
扩展而来的,并且是整个应用程序的起始类。
Making my best guess, I would say there are two possible reasons why you did this: 尽我最大的猜测,我会说您这样做有两个可能的原因:
Application
extending) class. Application
扩展)类复制的。 This is unlikely since you said you had a NullPointerException
, unless you manually called start()
. start()
,否则这不太可能,因为您说过您有NullPointerException
。 FXMLDocument.fxml
. FXMLDocument.fxml
。 This seems to be the likely case here. Assuming that you want the Application
extending class to be a controller, you need to create an instance of FXMLLoader
, instead of using the static method FXMLLoader.load()
. 假设您希望
Application
扩展类成为控制器,则需要创建FXMLLoader
的实例,而不是使用静态方法FXMLLoader.load()
。
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
loader.setController(this); // You need to set this instance as the controller.
Parent root = loader.load();
// Other stuff you need to do
productID.setCellValueFactory(new PropertyValueFactory<Product, String>("productID"));
This will set the currently running instance of UI
as the controller for FXMLDocument.fxml
. 这会将当前运行的
UI
实例设置为FXMLDocument.fxml
的控制器。
There are several points to take note. 有几点需要注意。
fx:controller
in FXML, or create a new instance of UI
(and setting it) as an alternative. fx:controller
,也不要创建新的UI
实例(并将其设置)作为替代。 You must provide the current instance to the FXMLLoader
. FXMLLoader
。 @FXML
will only be injected (ie non-null) after FXMLLoader.load()
has been called, or in initialize()
method. @FXML
注释的所有字段仅在FXMLLoader.load()
之后或在initialize()
方法中被注入(即非null)。 If you try to call productID.setCellValueFactory(new PropertyValueFactory<Product, String>("productID"));
productID.setCellValueFactory(new PropertyValueFactory<Product, String>("productID"));
, you may get a NullPointerException
, depending on the sequence of your codes. NullPointerException
,具体取决于代码的顺序。 Lastly, you do have an option of making another class the controller of the FXML file. 最后,您确实可以选择使另一个类成为FXML文件的控制器。 In fact, most people would do that as that is the purpose of MVC (which is the architecture JavaFX uses).
实际上,大多数人会这样做,因为那是MVC(JavaFX使用的体系结构)的目的。 Of course, all injected fields and initialization would also move to the new controller class.
当然,所有注入的字段和初始化也将移至新的控制器类。 Also remember that injected fields are
null
in constructor - so initialize in initialize()
of the new controller class. 还记得那场注入是
null
的构造-所以初始化initialize()
的新控制器类的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.