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));
// ...
}
我有一个永久 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));
// ...
}