title: How to gather frequent update/redraw/layout/refresh operations in SWT/Swing?
body: <p>I am doing some frequent operations, which require GUI refresh (adding some children to a control). </p>
  
  <p>I can't control the moment when the entire bunch of additions finished, so I can't do update/redraw/layout/refresh at the end and need do it each step.</p>
  
  <p>Simultaneously I need nod do it very frequent, because user need not see each change.</p>
  
  <p>Also each update/redraw/layout/refresh slows the process.</p>
  
  <p>So, I need to decide whether to update/redraw/layout/refresh by time. </p>
  
  <p>I wrote the following general class for SWT, but similar also applicable to Swing.</p>
  
  <p>Is it's logic complete and correct? Especially, will the check <code>delayedMap.get(doRun) == timer</code> work correctly in multithreading? It's purpose is to cancel delayed operation in the case if entering the <code>invokeOnceDelayed()</code> method is occured between enterings into <code>TimerTask.run()</code> and inner <code>synchronized</code> block?</p>
  
  <pre><code>public class SWTUtilities {
  
      private static HashMap&lt;Runnable, Timer&gt; delayedMap = new HashMap&lt;Runnable, Timer&gt;();
  
      public static void invokeLater(Runnable doRun) {
          Display.getDefault().asyncExec(doRun);
      }
  
      public static void invokeAndWait(Runnable doRun) {
          Display.getDefault().syncExec(doRun);
      }
  
      public static synchronized void invokeOnceDelayed(final Runnable doRun, long delay) {
  
          final Timer timer = new Timer(true);
          Timer oldTimer = delayedMap.put(doRun, timer);
          if( oldTimer != null ) {
              oldTimer.cancel();
          }
  
          timer.schedule(new TimerTask() {
  
              @Override
              public void run() {
                  synchronized(SWTUtilities.class) {
                      if( delayedMap.get(doRun) == timer ) {
                          invokeLater(doRun);
                      }
                  }
  
              }}, delay);
  
  
      }
  
  }
  </code></pre>