线程执行后刷新TableView

时间:2014-03-25 11:19:10

标签: java multithreading javafx-2

在我的应用程序中,我加载了一个包含数据的表。 在此选项卡中,一列来自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。 我在快照中尝试代码。我尝试了网络上发现的许多其他方法,但没有任何事情要做,该列绝望地是空的。

如果我保持线程循环但没有执行服务并设置默认值,则该列不为空。

屏幕刷新是一个真正的问题。

如何更新?

感谢。

1 个答案:

答案 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() {...} 方法,并且表列已正确绑定到它。