我的场景是用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);
并且没有错误,但是ListView在GUI中仍然是空的。
System.out.println(driversLV);
给出:
ListView@54f2d1d5[styleClass=list-view]
所以我的问题是:初始化ListView的正确方法是什么?尽管如此,我的代码是否正确?
答案 0 :(得分:2)
首先,不要在这里做任何静态的事情。控制器是与从FXML文件加载的UI相关联的对象,因此字段和方法需要是该对象的成员,而不是类的成员。 (以及FXMLLoader
will not initialize static fields。)
其次,使用@FXML
注释FXML文件中声明的字段。这将允许FXMLLoader
初始化它们,即使您将它们声明为私有(您应该这样做)。确保分配给FXML文件中控件的fx:id
与字段名称相同。
最后,FXMLLoader
将(默认情况下)通过调用其无参构造函数来创建控制器类的实例,然后它将初始化字段。因此,当然,在调用构造函数时,它们不会被初始化。相反,请使用initialize()
方法,FXMLLoader
将在注入@FXML
- 注释字段后自动调用。
所以你应该
public class MainDriversController{
@FXML
private ListView<String> driversLV;
private ObservableList<String> observableList = FXCollections.observableArrayList();
public 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" />
作为某个地方的元素。