在我的应用程序中,我加载了一个包含数据的表。 在此选项卡中,一列来自Web服务,可以进行一些时间来回答。 所以我在池线程中对待这个,以避免像这样阻止屏幕:
final ObservableList<StockListBean> list = FXCollections
.observableArrayList();
list.addAll(stocksListMService.getStocksListRunning());
stocksList.setItems(list);
final ExecutorService executor = Executors.newFixedThreadPool(4);
for (final StockListBean stockListBean : list) {
executor.execute(new Task<Float>() {
@Override
protected Float call() throws Exception {
logger.debug("In jfx task for {}", stockListBean.getCode());
((StockListRunningBean)stockListBean).setActualPrice(stocksListMService.getActualPrice(stockListBean.getCode()));
columnActualPrice.setVisible(false);
columnActualPrice.setVisible(true);
return 0f;
}
});
}
线程执行良好,数据在bean中设置得很好,但是我无法刷新tableView。 我在快照中尝试代码。我尝试了网络上发现的许多其他方法,但没有任何事情要做,该列绝望地是空的。
如果我保持线程循环但没有执行服务并设置默认值,则该列不为空。
屏幕刷新是一个真正的问题。
如何更新?
感谢。
答案 0 :(得分:2)
假设您的StockListRunningBean
使用JavaFX可观察属性,以便TableView查看更改,您不需要执行任何其他操作来更新表。您的代码的一个问题是您正在从不是FX应用程序线程的线程更改UI(通过更改StockListRunningBean price属性)。
尝试这种重构:
for (final StockListBean stockListBean : list) {
final int code = stockListBean.getCode(); // assuming int, change as required
final Task<Float> task = new Task<Float>() {
@Override
protected Float call() throws Exception {
logger.debug("In jfx task for {}", code);
return stocksListMService.getActualPrice(code);
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent event) {
((StockListRunningBean)stockListBean).setActualPrice(task.getValue());
}
});
executor.execute(task);
}
同样,这假设您的StockListRunnerBean有一个
public FloatProperty actualPriceProperty() {...}
方法,并且表列已正确绑定到它。