通过其他线程更新javafx上的listview

我需要在javafx上更新列表视图,我尝试了两种解决方案:

1。

Task task = new Task<Void>() {
    @Override public Void call() {
        while (true){
            visitsDataList = reqController.getVisits(userBean);
                Platform.runLater(() -> {
                    observableList.clear();
                    observableList.setall(visitsDataList);
                    listVisits.setItems(observableList);
                    listVisits.setCellFactory(List -> new CustomVisitRow());
        });
        try {
                Thread.sleep(10000);
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
    }
}
};

2。

new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            visitsDataList = reqController.getVisits(userBean);
            Platform.runLater(() -> {
                observableList.clear();
                observableList.setall(visitsDataList);
                listVisits.setItems(observableList);
                listVisits.setCellFactory(List -> new CustomVisitRow());});
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();}}}}).start();

但是我不相信,因为我相信创建了太多Runnable。还有其他解决方案吗? 我的哪种解决方案是最好的?

ab7788989 回答:通过其他线程更新javafx上的listview

每个循环都会使线程休眠十秒钟,这意味着您要创建一个Runnable并每十秒钟将其提交到 JavaFX Application Thread 上执行。十秒钟对计算机来说是永恒的。换句话说,您不会创建太多的Runnable对象,也不会使FX线程不知所措。但是,可以进行一些改进。

  1. 您不需要在每个循环中调用ObservableList#clear()ListView#setItemsListView#setCellFactory。例如,第一次创建和配置ListView时,只需设置一次单元工厂。并且假设在开始observableList之前已经在ListView上设置了Thread实例,然后调用#setAll就足够了。该方法等效于调用#clear,然后调用#addAll

    new Thread(() -> {
      while (true) {
        List<Visit> visits = reqController.getVisits(userBean);
        Platform.runLater(() -> observableList.setAll(visits));
        try {
          Thread.sleep(10_000L);
        } catch (InterruptedException ex) {
          break;
        }
      }
    }).start();
    
  2. 考虑改用javafx.concurrent.ScheduledService

    // ScheduledService class
    public class VisitRefreshService extends ScheduledService<List<Visit>> {
    
      private final ObjectProperty<User> userBean = new SimpleObjectProperty<>(this,"userBean");
      private final ObjectProperty<Controller> reqController = new SimpleObjectProperty<>(this,"reqController");
    
      // getters,setters,and property getters omitted for brevity
    
      @Override
      protected Task<List<Visit>> createTask() {
        return new Task<>() {
    
          final User user = getUserBean();
          final Controller controller = getReqController();
    
          @Override
          protected List<Visit> call() throws Exception {
            return controller.getVisits(user);
          }   
        }
      }
    }
    
    // Using the ScheduledService
    VisitRefreshService service = new VisitRefreshService();
    service.setReqController(...);
    service.setUserBean(...);
    service.setExecutor(...); // Or don't set to use the default Executor
    service.setPeriod(Duration.seconds(10.0));
    service.setOnSucceeded(event -> observableList.setAll(service.getValue()));
    service.setOnFailed(event -> service.getException().printStackTrace());
    service.start();
    
本文链接:https://www.f2er.com/3150784.html

大家都在问