如何从 FXML 文件初始化 ListView?

How can I initialize ListView from FXML file?

我的场景是用 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 的正确方法是什么?尽管如此,我的代码是否正确?

首先,不要将此处的任何内容设为静态。控制器是与从 FXML 文件加载的 UI 关联的 对象 ,因此字段和方法需要是该对象的成员,而不是 class 的成员. (还有 FXMLLoader will not initialize static fields。)

其次,使用 @FXML 注释 FXML 文件中声明的字段。这将允许 FXMLLoader 初始化它们,即使您将它们声明为私有(您应该这样做)。确保分配给 FXML 文件中控件的 fx:id 与字段名称相同。

最后,FXMLLoader 将(默认情况下)通过调用其无参数构造函数创建控制器 class 的实例,然后它将初始化字段。因此,当然,在调用构造函数时它们不会被初始化。相反,使用 initialize() 方法,一旦注入 @FXML-注释字段,FXMLLoader 将自动调用该方法。

所以你应该

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" />

作为某处的元素。