Java 线程执行后刷新TableView

Java 线程执行后刷新TableView,java,multithreading,javafx-2,Java,Multithreading,Javafx 2,在我的应用程序中,我用数据加载一个表。 在这个选项卡中,有一列来自一个Web服务,它可以让一些时间来回答。 所以我在池线程中处理这一个,以避免像这样阻塞屏幕: final ObservableList<StockListBean> list = FXCollections .observableArrayList(); list.addAll(stocksListMService.getStocksListRunning());

在我的应用程序中,我用数据加载一个表。 在这个选项卡中,有一列来自一个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;
             }
          });
    }
final ObservableList=FXCollections
.observableArrayList();
addAll(stocksListMService.getStocksListRunning());
存货清单.设置项目(清单);
final ExecutorService executor=Executors.newFixedThreadPool(4);
for(最终StockListBean StockListBean:list){
executor.execute(新任务(){
@凌驾
受保护的浮点调用()引发异常{
debug(“在{}的jfx任务中”,stockListBean.getCode());
((StockListRunningBean)stockListBean).setActualPrice(StocksListService.getActualPrice(stockListBean.getCode());
columnActualPrice.setVisible(false);
columnActualPrice.setVisible(true);
返回0f;
}
});
}
线程执行良好,数据在bean中设置良好,但我无法刷新tableView。 我在快照中尝试代码。我在网上尝试了很多其他的方法,但没什么可做的,专栏里空空如也

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

屏幕刷新真是个大问题

我怎样才能刷新这个


谢谢。

假设您的
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);
}
for(最终StockListBean StockListBean:list){
final int code=stockListBean.getCode();//假设为int,根据需要进行更改
最终任务=新任务(){
@凌驾
受保护的浮点调用()引发异常{
debug(“在{}的jfx任务中”,代码);
返回StocksListService.getActualPrice(代码);
}
};
task.setOnSucceeded(新的EventHandler(){
@凌驾
公共无效句柄(WorkerStateEvent事件){
((StockListRunningBean)stockListBean).setActualPrice(task.getValue());
}
});
执行者。执行(任务);
}
同样,这假设您的StockListRunnerBean具有
public FloatProperty actualPriceProperty(){…}

方法,并且表列已正确绑定到它。

我发现执行器不会抛出异常,只是关闭。如果将调用UI线程的方法包装在try块中,则可能会看到错误。调试和查找线程中的错误是一个真正的难题。如果发生异常,处理它们的方法是向任务注册
setOnFailed
处理程序:
task.setOnFailed(new EventHandler(){…})服务未引发异常。我的stockListBean不可观察,因为它被多个应用程序使用。我需要简单的变量类型。该任务允许在FX应用程序线程中获取线程。@James\u D用于让您知道发生了错误,这通常已经很明显了。它没有告诉你错误是什么,我需要一个堆栈跟踪。这有点欺骗性,因为task.call()说抛出异常,但如果我将start()方法包装在try-catch中,它就不会得到异常。@Kiva Compare-to。看看这是否有帮助。