我的场景是用 JavaFX Scene Builder 和 ListView 制作的。我希望它显示 xml 文件中的一些数据,但我不知道如何正确初始化此 ListView。
import javafx.collections.ObservableList;
import javafx.scene.control.ListView;
import application.Cparsing;
import javafx.collections.*;
public class MainDriversController{
private static ListView<String> driversLV;
static ObservableList<String> observableList = FXCollections.observableArrayList();
public static void SetListView(){
for(int x=0; x<Cparsing.driversNodes.getLength(); x++) {
observableList.add(Cparsing.driversNodes.item(x).getAttributes().getNamedItem("nick").getNodeValue());
}
driversLV.setItems(observableList);
System.out.println(driversLV);
}
}
这当然会给我 NullPointerException 因为它没有初始化。 我尝试添加
driversLV = new ListView<String>(observableList);
然后没有错误,但 GUI 中的 ListView 仍然是空的。
System.out.println(driversLV);
给出:
ListView@54f2d1d5[styleClass=list-view]
所以我的问题是:初始化ListView的正确方法是什么?尽管如此,我的代码是否正确?
首先,不要将此处的任何内容设为静态。控制器是一个与从 FXML 文件加载的 UI 关联的object,因此字段和方法需要是该对象的成员,而不是类的成员。 (并且
FXMLLoader
不会初始化静态字段。)
其次,用
@FXML
注释 FXML 文件中声明的字段。即使您将它们声明为私有(您应该这样做),这也将允许 FXMLLoader
初始化它们。确保 FXML 文件中分配给控件的 fx:id
与字段名称相同。
最后,
FXMLLoader
(默认情况下)将通过调用其无参数构造函数来创建控制器类的实例,然后它将初始化字段。因此,当然,当调用构造函数时它们不会被初始化。相反,请使用 initialize()
方法,一旦注入 FXMLLoader
带注释的字段,@FXML
将自动调用该方法。
所以你应该有
public class MainDriversController{
@FXML
private ListView<String> driversLV;
private ObservableList<String> observableList = FXCollections.observableArrayList();
@FXML
private void initialize(){
for(int x=0; x<Cparsing.driversNodes.getLength(); x++) {
observableList.add(Cparsing.driversNodes.item(x).getAttributes().getNamedItem("nick").getNodeValue());
}
driversLV.setItems(observableList);
System.out.println(driversLV);
}
}
当然,您的 FXML 文件的根元素中将包含
fx:controller="my.package.name.MainDriversController"
,并且
<ListView fx:id="driversLV" />
作为某处的元素。