javajavascriptgwt2

Modal window with progressbar for long tasks


In some cases, I want show to user a modal window with a progress bar when the long running query. (For individual UI items, I use the method setEnabled (true/ false) but I want more elegant solution.)

For example, in the entry point, until all elements not initialized -

public void onModuleLoad() {
   // initialization of the interface here
}

And also, for example, when completing the dependent list box (relationship one to many)

@UiHandler("listBox")
public void onListBoxChange(ChangeEvent event) {
   someService.findDependencies(id, new AsyncCallback<List<DependencyDTO>>() {
      public void onFailure(Throwable caught) {
         // exception handling here
      }
      public void onSuccess(List<DependencyDTO> data) {
         // listBox filling here
      }
   });
}

In Vaadin applications I can added to the listener the following code, for example -

...
Thread thread = new Thread() {
    @Override
    public void run() {                 
       // some initialization here 
       window.removeWindow(blockerWindow);
    }
};  

thread.start();             
blockerWindow = new BlockerWindow();
window.addWindow(blockerWindow);
...

In my case, I can use the following method to display a window with a progress bar -

private void freezeInterface() {
   blockerWindow = new BlockerWindow()
   blockerWindow.setGlassEnabled(true);
   blockerWindow.setAnimationEnabled(true);
   blockerWindow.setModal(true);
   blockerWindow.center();
   blockerWindow.show();
}

And the method to hide window -

private void unfreezeInterface() {
   blockerWindow.hide();
}

The question is, when hide the window.

For example, at the entry point there are series of queries -

...
service1.findDependenciesForListBox1(id1, new AsyncCallback<List<Dependency1DTO>>() {
   public void onFailure(Throwable caught) {
      // exception handling here
   }
   public void onSuccess(List<Dependency1DTO> data) {
      // listBox1 filling here
   }
});

service2.findDependenciesForListBox2(id2, new AsyncCallback<List<Dependency2DTO>>() {
   public void onFailure(Throwable caught) {
      // exception handling here
   }
   public void onSuccess(List<Dependency2DTO> data) {
      // listBox2 filling here
   }
});

serviceN.findDependenciesForListBoxN(idN, new AsyncCallback<List<DependencyNDTO>>() {
   public void onFailure(Throwable caught) {
      // exception handling here
   }
   public void onSuccess(List<DependencyNDTO> data) {
      // listBoxN filling here
   }
});     

And so on.

The answers come in a previously unknown sequence and hide the window in one of the methods onSuccess I can not.

I can use a timer, but I do not know beforehand the time which to pass in schedule.

...
blockerWindow.show();   
private void unfreezeInterface() {
   timer = new Timer() {
      public void run() {
         blockerWindow.hide();
      }
   };
   timer.schedule(15000);
}
...

How to properly implement this in GWT?


Solution

  • If you know the number of responses to get, you can use such approach:

    class TaskCompletedHandler{ // inner class
        private static final int NUMBER_OF_RESPONSES = 4;//just example
    
        private int tasksCompleted;
    
        public void notifyOfCompletedTask(){
            tasksCompleted++;
            if (tasksCompleted == NUMBER_OF_RESPONSES){
                blockerWindow.hide(); 
            }
        }
    }
    

    create instance of this class before showing modal window and then notify this handler in AsyncCallback

    service1.findDependenciesForListBox1(id1, new AsyncCallback<List<Dependency1DTO>>() {
       public void onFailure(Throwable caught) {
          taskCompletedHandler.notifyOfCompletedTask();
          // exception handling here
       }
       public void onSuccess(List<Dependency1DTO> data) {
          taskCompletedHandler.notifyOfCompletedTask();
          // listBox1 filling here
       }
    });