JavaFX - 自动更新选择框

JavaFX - Automatically update a choiceBox

我有一个永久 updates/creates 列表的线程:

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 控制器,它将那个列表添加到一个 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 的内容更新为 'devices' 列表包含的任何值?

两期:

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

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

只是在每次迭代时将一个新列表分配给变量 devices。由于controller中的initialize()方法只是获取了一次引用,当你更新devices到一个新的列表时,它不再是controller中引用的列表

你需要一些类似

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

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

此时,您可能不再需要 query() 到 return 可观察列表,常规列表即可:

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));
    // ...
}