PorgressbarIndicator hack does not work for Runnable

I have a Computation class where I do some computation in a thread and update Java Bean. The update values are reflected back to the UI using the progress-bar hack. Unfortunately this only works when the computation class extends thread but not when the thread is executed via ExecutorServices. I have the same exact code except instead of extending thread, I implemented Runnable and instead of calling Thread.start(), I used Executor.execute(). The UI won’t update. Any ideas as to why this might be happening?

Original Working code:


public class ComputationClass extends Thread {
    private static final ProgressIndicator progressIndicator;
    static {
        progressIndicator = new ProgressIndicator();
        progressIndicator.setIndeterminate(true);
        progressIndicator.setWidth("0");
        progressIndicator.setHeight("0");
    }
    
   void some method() {
          getApplication.getWindow().addComponent(progressIndicator);
          this.start();
   }
    
    public void run() {
         magic
    }

}

Broken Code


public class ComputationClass Implements Runnable {
    private static final ProgressIndicator progressIndicator;
    static {
        progressIndicator = new ProgressIndicator();
        progressIndicator.setIndeterminate(true);
        progressIndicator.setWidth("0");
        progressIndicator.setHeight("0");
    }
    
   void some method() {
          getApplication.getWindow().addComponent(progressIndicator);
          ExecutoreServiceObject.execute(this);
   }
    
    public void run() {
         magic
    }

}

You should never, EVER, share a component with the ‘static’ keyword. And I have no idea what ‘ExecutoreServiceObject’ is, so can’t help you there.

Thanks for the tip.

ExcutorService executorServiceObject = Executors.newCachedThreadPool();

Could you define ‘does not work’? are you sure that your ‘thread’ is actually executed? BTW, the Refresher add-on is basically the same as a a hidden ProgressIndicator, but won’t cause layouting or other such issues.

Yes, it executes as hitting the refresh button shows the correct values. Also, I’ve traced it using a debugger. As for not working, I mean doesn’t pull data from the server. So, when the user hits “Calculate” button, the first methods displays the values right away or a blink later. But for the latter solution, it doesn’t display the values until I refresh or press calculate again.

Another interesting finding, I have removed all threads and now they are all under one single thread. All the calculations are done at once (within the same method). When I press calculate, some calculations are rendered in the UI and some are not. Makes no sense. This only happens for the first time I press calculate. After I change some values in the field and press calculate again, they all render immediately.

May need to setImmediate(true) to the component you are trying to refresh

Tried that, still doesn’t work. What seems to work is requestRepaintAll() . Actually requestRepaintAll() seems to solve a lot of my problems, allows me write way cleaner code. Why isn’t it a good idea to use it?

Normally, if Vaadin APIs are used correctly and background threads are managed correctly, application code should never need to call those methods. Instead, the framework calls them whenever it is informed of a change.

Typical causes for this not happening include bypassing Vaadin data APIs when modifying a container or data shown indirectly in one. There might be some situations where indirectly referenced data changes and an explicit call may help, but such code might break in future versions of the framework.

Also, e.g. lack of correct synchronization in a background thread etc. could cause such problems, although in that case they would probably not happen systematically but only rarely.

No wonder, I was wondering how vaadin gets notified of changes in POJO. I’m using Observer pattern to notify the Calculator class. I’m going to try using Vaadin data containers see if that helps. Thanks.

Edit: Is there a way to fire an event from the data object to notify vaadin of changes?

No generic public API (would not make sense for many containers anyway), but some containers might have API for that - possibly with visibility “protected”.

From the contained data object itself (bean/entity/…), there is no reference to the container unless you add one in your data objects, and as far as I know, Oracle is not planning to integrate JSR-295 (beans binding) so the JVM/JRE does not really enable listening to changes to the bean.

Thanks for you help guys. It seems my problems were, as stated by Henri Sara, not using Vaadin data API. I have solved my problems using PropertysetItem.