progressbar in a thread does not update its UI until the work was done in the main thread

前端 未结 3 1181
北恋
北恋 2020-12-21 18:08

i am cutting a big file into blocks, and want to display the rate of the progress. when i click startCut Button, here is the code to execute:

FileInputStream         


        
相关标签:
3条回答
  • 2020-12-21 18:46

    The crux of the problem is that you're updating the component: pbCompleteness on a thread other than the Event Dispatch Thread. You can remedy this using SwingUtilities.invokeLater from within your run() method; e.g.

    AtomicInteger value = new AtomicInteger(0);
    while (true) {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          pbCompleteness.setValue(value.get());
        }
      });
    
      // Do some work and update value.
    }
    

    This will cause the JProgressBar to be updated (and repainted) on the Event Dispatch thread as your worker thread continues to run. Note that in order to refer to value within the "inner" anonymous Runnable instance I have changed it to be an AtomicInteger. This is also desirable as it makes it thread-safe.

    0 讨论(0)
  • 2020-12-21 18:54

    You've got two problems here:

    • You're doing long-running work in the Swing dispatcher thread, which means you're stopping it from processing events. (Try moving windows around etc - it will fail.)
    • You're updating the UI from the wrong thread at point A. It sounds like you're getting away with this at the moment, but it's still a bug.

    You should use SwingWorker or SwingUtilities to address both of these issues. Basically, you mustn't access the UI from a non-UI thread, and you mustn't do long-running work on a UI thread. See the Swing concurrency tutorial for more information.

    0 讨论(0)
  • 2020-12-21 18:56

    i found a very simple way to this prob :D . you can use this code and very simlpe handel this error :).

    int progress=0;
    Random random = new Random();
    while (progress < 100) {
     //Sleep for up to one second.
     try {
           Thread.sleep(random.nextInt(100));
    } catch (InterruptedException ignore) {}
    progress+=1;
    progressBar.setValue(progress);
    Rectangle progressRect = progressBar.getBounds();//important line 
    progressRect.x = 0;
    progressRect.y = 0;         
    progressBar.paintImmediately(progressRect);//important line 
     }
    
    0 讨论(0)
提交回复
热议问题