我有一个永久更新/创建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;列表举行?
答案 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));
// ...
}