在 Vaadin 14 中使用线程更新 UI

问题描述

我创建了一个线程(通过 lambda 表达式)来根据用户输入字段获取一些数据,但是当我在检索数据时尝试单击下拉菜单时,我得到了迷你进度条指示器。那么是否正在创建一个新线程?我在这里做错了什么?

Button docomputation = new Button("Get Results);
docomputation.addClickListener(event -> {
        UI ui = UI.getCurrent();
        new Thread(() -> {
             
             // Do some work
             ui.access(() -> layout.add(results);

        }).start();
});

更新:已解决!进行了不必要的 ui.access 调用,从而锁定了资源。感谢所有评论和帮助的人。

解决方法

代码在我看来是正确的(除了 ui.access 后面缺少的结束括号)。这是唯一的 ui.access 调用吗?这是您在其中所做的全部工作吗?

我制作了这个示例以供参考,组合框在后台任务运行时保持响应。

@Route
public class ThreadView extends VerticalLayout {

    public ThreadView() {
        Button runThreadButton = new Button("Start thread",e -> {
            UI ui = UI.getCurrent();
            new Thread(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                ui.access(() -> Notification.show("Completed"));
            }).start();
        });
        ComboBox<String> comboBox = new ComboBox<>("Items","One","Two","Three");
        add(runThreadButton,comboBox);
    }
}
,

那么是否正在创建一个新线程?

您可以通过添加 System.out.println("Thread started") 并检查是否打印该消息,或通过在调试模式下运行您的应用程序并在您感兴趣的部分上设置断点来验证这一点。

我在这里做错了什么?

您展示的代码看起来不错。我猜想在显示的代码之外存在问题,即您忘记了您还需要添加 @Push 注释。没有那个注解,服务器将无法直接向客户端发送消息。