title: Cannot update Swing component under a heavy process
body: <p>I am running a very heavy process under an anonymous <code>SwingWorker</code> thread. In the meantime, I'm reporting progress to the GUI using a progress bar. However, Swing threading is doing me in. It's simply not updating anything in time. I'm not sure how to do it, as I've tried updating the GUI from the <code>SwingWorker</code> thread, and outside, and both refuse to work.</p>
  <h2><strong>How can I reliably update the Swing UI while a heavy worker thread is running?</strong></h2>
  <h3>Things I've tried</h3>
  <p>This does not work (with or without wrapping in the <code>invokeLater</code> command).</p>
  <pre><code>new LocalCompressor(compressor).execute();
  
  while (!compressionDone) {
      SwingUtilities.invokeLater(new Runnable() {
      
          @Override
          public void run() {
              int percent = compressor.getPercentDone();
              progressBar.setValue(percent);
              statusLabel.setText(percent);
          }
      });
  }
  </code></pre>
  <hr>
  <p>Additionally, attempting to update the UI from a concurrent measuring thread does not work:</p>
  <pre><code>class LocalCompressor extends SwingWorker&lt;Void, Void&gt; {
  
      // [...]
      
      public LocalCompressor(Compressor compressor) {
          this.compressor = compressor;
          
          // [...]
      }
      
      @Override
          protected Void doInBackground() {
          
              final Thread t1 = new Thread(new Runnable() {
              
                  @Override 
                  public void run(){
                      compressor.compress();
                  }
              });
              
              final Thread t2 = new Thread(new Runnable() {
              
                  @Override
                  public void run() {
                  
                      t1.start();
                      
                      while (t1.isAlive()) {
                          updateUI(compressor.getPercentDone());
                      }
                  }
              
              });
              
              t2.start();
              
              return null;
          }
          
          // [...]
  }
  </code></pre>