2

I have an async-thread running that is periodically checking a database for an insert to occur. When the record is found, the UI is then loaded.

The UI.push() method works correctly when a large amount of data is loaded and significant UI changes have occured. Where I am having issues, is when pushing a Label.setValue() change back to the client.

The code for the update to the Label is:

Label displayProgress;

...

private void updateProgress(final int status) {
    CustomUI.getInstance().access(new Runnable() {
        @Override
        public void run() {
            LOG.log(Level.INFO, "Running progress text update");
            StringBuilder sb = new StringBuilder(100);

            String desc = StateManager.getDescription(status);
            Integer step = StateManager.getStatusIndex(status);

            sb.append("Step ").append(step).append(" of ").append(StateManager.getStatusCount());
            sb.append("\n").append(desc);

            displayProgress.setValue(sb.toString());
            //displayProgress.markAsDirty();

            LOG.log(Level.INFO, sb.insert(0, "Progress text should be: ").toString());

            CustomUI.getInstance().push();
        }
    });
}

My CustomUI class has the following annotation added:

@Push(value = PushMode.MANUAL, transport = Transport.STREAMING)

This code is called ~10 secs inside the async-thread. The logging shows the correct outputs I am expecting, however the Label will never display. The label is viewable to the client if working correctly.

Other implementations I have tried, with no success:

  • Using UI.setPollInterval(10000)
  • Push transport values of STREAMING and WEBSOCKET
  • Other displayable components inplace of Label
  • Manually marking display component as dirty
  • Component.Immediate values of true and false

The server I am using is Apache Tomcat/7.0.42 with JVM 1.6. I am unable to change or update anything on the server so I am limited to modifing only application settings and project files to solve this problem. Hopefully somebody else has solved this issue already and can help me out.

Thanks

Sean
  • 398
  • 2
  • 13
  • Your label should be guarded by a lock or marked as valotile in order to be visible to the thread that displays it.... – Mike Dec 02 '13 at 20:54
  • @Mike No need for the `volatile` nor lock if that `Label` object is touched only from the main Vaadin UI thread. That appears to be the case here. – Basil Bourque Jan 06 '15 at 22:51

1 Answers1

1

I finally found the solution to this problem.

Calling Label.markAsDirty() does work... assuming you are using Vaadin 7.1.1+. If still using Vaadin 7.1.0 (which I am) you will need to lock the session first, otherwise you will fail the assert in the Label.markAsDirty() method.

VaadinSession.getCurrent().lock();
Label.markAsDirty();
VaadinSession.getCurrent().unlock();
Sean
  • 398
  • 2
  • 13
  • 2
    This answer may be outdated. Push improved significantly in Vaadin 7.2 and 7.3. Also, the web servers (Tomcat, Jetty, and such) have improved, such as WebSocket implementation replaced in later versions of Tomcat 7 and 8. I posted [this answer](http://stackoverflow.com/a/27808461/642706) on another question showing a minimal example of Push in Vaadin 7.3.7. My code uses a background thread to update every second the current time displayed in a Label’s text. That example requires none of the tricks shown here. – Basil Bourque Jan 06 '15 at 22:57
  • Hi Basil! it seems i have the similar issue that u had then: i have to update my DateField field once a sec. i use Vaadin 7.6. How did u made the DateField fld update its value on-fly, w/o page refresh or reload? Thanks. – user1053031 Jun 02 '16 at 11:28