JavaFX - 自动更新choiceBox

时间:2015-02-02 02:23:55

标签: javafx observable

我有一个永久更新/创建List的线程:

private ObservableList<String> query() {
    try {
        return FXCollections.observableArrayList(getWMIValue(query, fieldName));
    } catch (Exception e) {
        return FXCollections.observableArrayList("");
    }
}

@Override
public void run() {
    while (true) {
        devices = query();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(WmiAccess.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

public ObservableList<String> getDevices() {
    return devices;
}

我有一个JavaFX fxml控制器,它将List添加到ChoiceBox

@Override
public void initialize(URL url, ResourceBundle rb) {
    wmiAccess = new WmiAccess(
            "SELECT * FROM Win32_PnPEntity", "Name"
    );

    Thread wmiThread = new Thread(wmiAccess);

    wmiThread.start();

    choiceBox.setItems(wmiAccess.getDevices());

}

我现在的问题是:ChoiceBox没有自动更新其内容。如何设置将choiceBox的内容更新为&#39;设备&#39;列表举行?

1 个答案:

答案 0 :(得分:1)

两个问题:

首先,您没有更新同一个列表,而是每次都创建一个新列表:

while (true) {
    devices = query();
    // ...
}

在每次迭代时只为变量devices分配一个新列表。由于控制器中的initialize()方法只获取一次引用,当您将devices更新为新列表时,它不再是从控制器引用的列表。

你需要一些基本的东西

while (true) {
    devices.setAll(query);
    // ...
}

当使用devices实例化该类时,您需要确保devices = FXCollections.observableArrayList();已正确初始化。

此时,你可能不再需要query()来返回一个可观察列表,常规列表会这样做:

private List<String> query() {
    try {
        return getWMIValue(query, filename); // I'm guessing that returns a list...
    } catch (Exception e) {
        return Collections.emptyList();
    }
}

第二个问题是你的非终止循环是在后台线程中运行的。如果devices是组合框中的项目列表,则只能在FX应用程序线程上更新它。所以你需要做一些像

这样的事情
while (true) {
    List<String> latestDevices = query();
    Platform.runLater(() -> devices.setAll(latestDevices));
    // ...
}