2017-03-16 47 views
0

我有我的场景用JavaFX Scene Builder和ListView制作。我希望它显示来自xml文件的一些数据,但我不知道如何正确初始化这个ListView。如何从FXML文件初始化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); 

给出:

[email protected][styleClass=list-view] 

所以我的问题是:什么是初始化ListView控件的正确方法?尽管如此,我的代码是否正确?

回答

2

首先,这里不要做任何事情。控制器是与从FXML文件加载的UI关联的对象,所以字段和方法需要是该对象的成员,而不是该类的成员。 (和FXMLLoaderwill not initialize static fields。)

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

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

所以,你应该有

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

为元素的地方。

+0

Thaaaaaaaaaaank你!从昨天开始尝试了很多方法,它只是initialize()方法! :) – Sheb