2

I have a function which is called on a click of a button and it takes a long time to create and append to the DOM some elements so I would like to display a PopupPanel with a "loading" icon while the function finished what it has to do. Please note that my function does not make a call to the server, it only creates some elements in the UI which take a long time to compute, so I don't have an onSuccess() event or a callback function to work with.

So I have my PopupPanel:

pp = new PopupPanel();
pp.setTitle("loading....");
pp.setGlassEnabled(true);

Then on the click handler I have the following code:

public void onClick(ClickEvent event) {
  pp.show();
  functionWhichTakesaLongTimeToExecute();               
  pp.hide();
}

Since JavaScript is single-threaded I was expecting that the PopUp will appear, then functionWhichTakesaLongTimeToExecute() executes and then the PopUp to be hidden but what happens is that functionWhichTakesaLongTimeToExecute() executes first, taking a long time to append the elements to the DOM, and only after it has finished doing its job is the PopUp shown and then hidden. It is as if like the code was:

functionWhichTakesaLongTimeToExecute(); 
pp.show();                  
pp.hide();

What bothers me even more is that if I add a Window.alert("test") after pp.show() this will break the flow until the OK button in the alert is pressd and this causes the PopUp to appear before the alert and before functionWhichTakesaLongTimeToExecute() is called. So the following code works as expected:

pp.show();
Window.alert("test");
functionWhichTakesaLongTimeToExecute();                 
pp.hide(); 

Can somebody please explain to me why the PopUp is not displayed before the functionWhichTakesaLongTimeToExecute() is called but instead it "waits" for functionWhichTakesaLongTimeToExecute() to execute and only after that it gets to be displayed and why adding a Window.alert("test") causes it to be displayed properly?
PS: I have tested the code in both IE8 and Chrome and the behavior is the same.

vlad1918
  • 338
  • 3
  • 15

2 Answers2

5

This is how you can do it:

pp.show();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {

    @Override
    public void execute() {
        functionWhichTakesaLongTimeToExecute();
        pp.hide();
    }
});

I explain it here: GWT: Timer and Scheduler Classes

Community
  • 1
  • 1
Andrei Volgin
  • 40,755
  • 6
  • 49
  • 58
  • 1
    As a side-note, I build some very complicated UIs, and they never take more than 100 milliseconds to build. You may want to explore why your UI takes so long to render. There must be some ways to optimize it. – Andrei Volgin Mar 11 '14 at 17:05
  • I tried your code out but it didn't work. However I managed to use Timer to do what I needed. Timer tmr = new Timer() { @Override public void run() { functionWhichTakesaLongTimeToExecute(); pp.hide(); } } }; tmr.schedule(100); – vlad1918 Mar 12 '14 at 08:05
0

I have had some issues while using setGlassEnabled as well. Can you check by removing the setGlassEnabled(true) line from your code and see if it works?

Also one more thing that I happened to note is that, you have not added any widgets to your PopupPanel. In the source code for PopupPanel it is mentioned that you mustattach a child widget to your PopupPanel object before show is called. http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/user/client/ui/PopupPanel.java

Do try both of these and let me know if either of it works.

somesh
  • 2,509
  • 3
  • 16
  • 24
  • Tried it out with a Label added to the PopupPanel and with setGlassEnabled(false). Still not working with Scheduler. But it works with the Timer class workaround though. – vlad1918 Mar 13 '14 at 06:50