1

I have an onClick event in Java Swing.

private void fastForward(java.awt.event.MouseEvent evt) { 
    loading.setVisible(true);
    //some time consuming algorithm
    loading.setVisible(false);      
}

In it, I perform a operation that consumes a lot of time, so I want to display a loading animation.

I created one as a button with a icon which a loading gif, I set the visibility of the button to false. In the onClick event I set the visibility to true. The problem is that button becomes visible when the whole function executes, which is not what I want. I want the button to be displayed during the execution of the function. How can I set the button to visible during execution.

blackpanther
  • 10,998
  • 11
  • 48
  • 78
Borut Flis
  • 15,715
  • 30
  • 92
  • 119

2 Answers2

5

That is because, only once the UI thread gets free, it can update the UI. This is what you need to do:

private void fastForward(java.awt.event.MouseEvent evt) { 
    loading.setVisible(true);
    new Thread(new Runnable(){

    @Override
    public void run(){
       //time consuming algorithm.
       if(done){
         SwingUtilities.invokeLater(new Runnable(){
             @Override public void run(){
                loading.setVisible(false);      
           }
          });
       }
    }

    }).start();
}

Above what happens is this:

  1. UI thread sets the loading status.
  2. UI thread starts a new Thread to execute the command. UI thread is free after this call.
  3. The new Thread computes the algorithm
  4. Once the new thread is done, it requests the UI thread to update the UI

This way, the button wont get freezed. And on completion, UI thread gets updated.

Jatin
  • 31,116
  • 15
  • 98
  • 163
  • +1. But I don't think `SwingUtilities.runLater` exists. You probably meant `SwingUtilities.invokeLater`. – Guillaume Polet Apr 24 '13 at 11:52
  • 1
    @GuillaumePolet Thanks. Updated it. I have been working with `JavaFX`for sometime now and it has `Platform.runLater()`, hence wrote it mistakenly. – Jatin Apr 24 '13 at 11:55
2

Try using a SwingWorker

It has in built functionality to re-sync with the Event Dispatching Thread through the use of the publish/process methods. It easy to know when its done and has progress update capabilities

Take a look at this, this and this for examples

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366