Vaadin 8:如何从另一个线程更新模态表单上的标签值

Vaadin 8: How to update a label value on a modal form from another thread

我正在使用 vaadin 8,我需要更新模态上的标签值。

在下面的列表中,一个标签值在一个 while(true) 循环内,正在从另一个 Thread 执行:

      modal.show();
        modal.getUI().access(new Runnable() {
                    @Override
                    public void run() {
                        while(true) {
                        sleep(1000)
                        ....
                        break_condition;
                        break;
                        }
                        modal.getLabel().setValue("xxxx")
                    }
        });

在此过程中,屏幕会冻结,最后出现模态 windows 并修改标签值。是否可以不冻结屏幕?

尝试放松引入睡眠的 while 循环执行。这可以避免屏幕冻结:

Thread.sleep(50);

可能的解决方案...

class TaskCycle implements Runnable {

    MyModal modal;

    public TaskCycle(MyModal modal){
      this.modal = modal
    }

        @Override
        public void run() {
           while(true) {
             sleep(1000)
              ....
             break_condition;
             break;
           }
           modal.getLabel().setValue("xxxx");
           modal.getLabel().getUI().push();
        }    
    }


MyModal modal = new MyModal();
modal.show();

TaskCycle r = new TaskCycle (modal);    
Thread t = new Thread(r);
t.start();

总的来说,这个解决方案效果很好,但需要配置一个"vaadin server-push"(参见官方文档)。

不幸的是,我使用的是 Liferay 7,推送服务器(vaadin 8 的)不工作。

在我的例子中,这个解决方案不是最好的,因为只有在浏览器 window/tab 上执行 "resize" 时,模态才会更新为新值(由线程提供)。

为了 "simulate" 调整大小,可以插入函数:

setPollInterval(1000);
UIEvents.PollListener poll = new UIEvents.PollListener(){

            @Override
            public void poll(UIEvents.PollEvent event) {
                System.out.println("Poll interval start!!!!!");
            }
        };
UI.getCurrent().addPollListener(poll);

删除侦听器:

UI.getCurrent().removePollListener(poll);

对于无法使用 push() 函数的所有用户来说,这是一个很好的解决方法。