Question about ui.access

I have implemented polling in my application to handle updating the client with some information from the server. Right now I am just updating the date and time on the screen, but in the future I plan on doing more. One of my testers had noted that their screen flickers sometimes when the update happens, and when testing from home has notice that the screen gray’s out for a second every so often. This is not something that happens all the time, but it is happening frequently.

In my UI I added the following code:

[code]
public class MessageCheck implements Runnable {
String info = “”;
Long prevHeartBeat = 0l;
Long prevTime = 0l;
Long currHeartBeat = 0l;
Long currTime = 0l;
Long diffTime = 0l;

    @Override
    public void run() {
        prevHeartBeat = getLastHeartbeatTimestamp();
        prevTime = Calendar.getInstance().getTimeInMillis() / 1000l;
        
        while (msgChkActive) {
            info = getInfo();
            
            currHeartBeat = getLastHeartbeatTimestamp();
            currTime = Calendar.getInstance().getTimeInMillis() / 1000l;
            
            if (!prevHeartBeat.equals(currHeartBeat)) {
                prevHeartBeat = currHeartBeat;
                prevTime = currTime;
            }
            
            diffTime = currTime - prevTime;
            
            if (diffTime >= 180) {
                msgChkActive = false;
            }
            
            access(new Runnable() {

                @Override
                public void run() {
                    main.setStatusMessage(info);            
                }
            });
            
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                return;
            }
        }
        
        handleClose();
    }
}    

[/code]And after I start my UI running and load my main screen, I start MessageCheck as a new thread.

Here are my questions.
First do I need to use UI.access? From everything I have read I do, but I just wanted to verify.
Second, what could be causing the screen to flicker or gray out when this update happens and how can I correct that?
Thirdly, is there a better way to handle this?

Hello,

Yes, UI.access is absolutely necessary here. I don’t know what causes the flickering, more info might be helpful.

Regarding another way to handle this. Because your thread is only active once in 30 seconds and the data doesn’t come at random points of time, you can avoid wasting a thread resource and delegate the timer to the client.

  1. Write a method to update the values on the screen
  2. Register this method as a JavaScript function
  3. Call it from JavaScript wrapped into setTimer.

Here’s some info:

https://vaadin.com/book/vaadin7/-/page/advanced.javascript.html

So your code will look something like this:

JavaScript.getCurrent().addFunction("infoUpdate",  a -> {
   main.setStatusMessage(getInfo());
   JavaScript.getCurrent().execute("setTimer(infoUpdate, 30000)");
});

Hopefully it does the job, I think it’s less complicated and more efficient :slight_smile:

Thanks for the information, I just have one question regarding where the JavaScript code should be added.

The JavaScript solution on the surface seems to be the best option. I just have one question regarding where the code you supplied should be placed. My main application screen is broken down into two parts. The frist is the UI class, which really does not have any UI components loaded into it. The second is a CustomComponent called MainPage (main in the UI class). The button whose caption, I am changing is in MainPage.

So the question is should I add the JavaScript to the MainPage class or the UI class?

Thank you

Tried putting the code in both the UI and the MainPage CustomComponent and the compiler does not like it. The addFunction wants the name of the JavaScript function, which is a fine and then a JavaScriptFuction class, which requires a :“call” method. This is shown in the documentation, and does no seem to matchup with what you have shown in your post.

What am I missing?

I’d say that in this case it better be in the MainPage class, as the JS code updates it.

In my code I’m using Java 8 syntax (lambda), you don’t seem to have it, so just follow the example in the book, it uses older anonymous classe syntax.

Okay, got the code to work and that solved the issue. Posting my code here in case it helps others.

        JavaScript.getCurrent().addFunction("infoUpdate", new JavaScriptFunction() {
            @Override
            public void call(JSONArray arguments) throws JSONException {
                Date currDate = new Date();
                Long data = null;
                
                if (arguments != null && arguments.length() > 0 ) {
                    data = arguments.getLong(0);                    
                }
                            
                if (data != null) {
                    currDate = new Date((Long)data);
                }
                
                setStatusMessage(getInfo(currDate));
                
                JavaScript.getCurrent().execute("setTimeout(function(){infoUpdate(new Date())},30000)");
            }            
        });
        
        JavaScript.getCurrent().execute("infoUpdate(new Date())");

Thank you

Well I thought it solved the problem, but it has not. Here are the two methods that are being called in the java script on the server. Is there a better way of doing this?
public void setStatusMessage(String message) {
this.btn_Info.setCaption(message);
}

public String getInfo(Date currDate) {
    SimpleDateFormat sdfDate = new SimpleDateFormat("MMM dd yyyy HH:mm");
    String info = sdfDate.format(currDate);

    return info;
}    

Thank you