Search code examples
javamultithreadingvaadin8

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


I am using vaadin 8, and I need to update a label value on a modal.

In the listing below, a label value is inside a while(true) cycle being executed from another Thread:

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

During the process, the screen will freeze and the modal windows appears at the end with the label value modified. Is it possible to do without freezing the screen?


Solution

  • A possible solution...

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

    In general, this solution works well but needs of the configuration of a "vaadin server-push" (see the officical documentation).

    Unfortunately I am using Liferay 7 and the push server (of vaadin 8) does not work.

    This solution in my case is not the best, because the modal is updated with the new values (provided by the thread), only if you perform a "resize" of the browser window/tab.

    In order to "simulate" the resize it is possible to insert the function:

    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);
    

    to remove listener:

    UI.getCurrent().removePollListener(poll);
    

    this is a good workaround for all users that can't use the push() function.