如何从FXML文件初始化ListView?

时间:2017-03-16 18:03:53

标签: java listview javafx fxml scenebuilder

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

1 个答案:

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

作为某个地方的元素。