如何从 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" />
作为某处的元素。
我的场景是用 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" />
作为某处的元素。