简体   繁体   English

由其他线程更新 javafx 上的列表视图

[英]Update listview on javafx by other thread

I need to update a listview on javafx, i tried two solution:我需要更新 javafx 上的列表视图,我尝试了两种解决方案:

1. 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. 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();

but I am not convinced because I believe that too many Runnable are created.但我不相信,因为我相信创建了太多的 Runnable。 there are other solutions?还有其他解决方案吗? which of my solutions is the best?我的哪个解决方案是最好的?

Every loop you sleep the thread for ten seconds, which means you're creating a Runnable and submitting it for execution on the JavaFX Application Thread once every ten seconds.每个循环都会使线程休眠十秒钟,这意味着您正在创建一个Runnable并将其提交以每十秒钟在JavaFX 应用程序线程上执行一次。 Ten seconds is an eternity to a computer.十秒钟对计算机来说是永恒的。 In other words, you are not creating too many Runnable objects nor are you overwhelming the FX thread.换句话说,您没有创建太多Runnable对象,也没有压倒 FX 线程。 However, there are some improvements that could be made.但是,可以进行一些改进。

  1. You don't need to call ObservableList#clear() , ListView#setItems , or ListView#setCellFactory every loop.您不需要在每个循环中调用ObservableList#clear()ListView#setItemsListView#setCellFactory For one, setting the cell factory only needs to happen once when you first create and configure the ListView .一方面,设置单元工厂只需要在您第一次创建和配置ListView时进行一次。 And assuming the observableList instance has been set on the ListView before starting your Thread then calling #setAll is sufficient.并假设在启动Thread之前已在ListView上设置了observableList实例,那么调用#setAll就足够了。 That method is equivalent to calling #clear followed by #addAll .该方法相当于调用#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. Consider using a javafx.concurrent.ScheduledService instead.考虑改用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM