title: Swing/JFrame vs AWT/Frame for rendering outside the EDT
body: <p>What are the principle differences between using an AWT Frame and a Swing JFrame when implementing your own rendering and not using standard Java GUI components?</p>
  
  <p>This is a follow on from a previous question:</p>
  
  <p><a href="https://stackoverflow.com/questions/6824756/awt-custom-rendering-capture-smooth-resizes-and-eliminate-resize-flicker/6893310#comment-8211192">AWT custom rendering - capture smooth resizes and eliminate resize flicker</a></p>
  
  <p>The typical talking points on Swing vs AWT don't seem to apply because we're only using frames.   Heavyweight vs Lightweight goes out the window (and JFrame extends Frame), for example.</p>
  
  <p>So which is best, JFrame or Frame for <strong>this situation</strong>?  Does it make any meaningful difference?</p>
  
  <p>Note: this scenario is one where <strong>rendering in the EDT is not desirable</strong>.  There is an application workflow which is not linked to the EDT and rendering is done on an as-needs basis outside of the EDT.  To synchronize rendering with the EDT would add latency to the rendering.  We are not rendering any Swing or AWT components other than the Frame or JFrame (or an enclosed JPanel/Component/etc if it is best).</p>
  
  <pre><code>import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.Graphics;
  import java.awt.Insets;
  import java.awt.Toolkit;
  import java.awt.image.BufferStrategy;
  import java.awt.Frame;
  
  public class SmoothResize extends Frame {
  
  public static void main(String[] args) {
      Toolkit.getDefaultToolkit().setDynamicLayout(true);
      System.setProperty("sun.awt.noerasebackground", "true");
      SmoothResize srtest = new SmoothResize();
      //srtest.setIgnoreRepaint(true);
      srtest.setSize(100, 100);
      srtest.setVisible(true);
  }
  
  public SmoothResize() {
      render();
  }
  
  private Dimension old_size = new Dimension(0, 0);
  private Dimension new_size = new Dimension(0, 0);
  
  public void validate() {
      super.validate();
      new_size.width = getWidth();
      new_size.height = getHeight();
      if (old_size.equals(new_size)) {
          return;
      } else {
          render();
      }
  }
  
  public void paint(Graphics g) {
      validate();
  }
  
  public void update(Graphics g) {
      paint(g);
  }
  
  public void addNotify() {
      super.addNotify();
      createBufferStrategy(2);
  }
  
  protected synchronized void render() {
      BufferStrategy strategy = getBufferStrategy();
      if (strategy == null) {
          return;
      }
      // Render single frame
      do {
          // The following loop ensures that the contents of the drawing buffer
          // are consistent in case the underlying surface was recreated
          do {
              Graphics draw = strategy.getDrawGraphics();
              Insets i = getInsets();
              int w = (int)(((double)(getWidth() - i.left - i.right))/2+0.5);
              int h = (int)(((double)(getHeight() - i.top - i.bottom))/2+0.5);
              draw.setColor(Color.YELLOW);
              draw.fillRect(i.left, i.top + h, w,h);
              draw.fillRect(i.left + w, i.top, w,h);
              draw.setColor(Color.BLACK);
              draw.fillRect(i.left, i.top, w, h);
              draw.fillRect(i.left + w, i.top + h, w,h);
              draw.dispose();
  
              // Repeat the rendering if the drawing buffer contents 
              // were restored
          } while (strategy.contentsRestored());
  
          // Display the buffer
          strategy.show();
  
          // Repeat the rendering if the drawing buffer was lost
      } while (strategy.contentsLost());
  }
  
  }
  </code></pre>