title: Effect of Paint delayed by up to 500ms
body: <p>I have a Java program which displays time in deciseconds. Each digit is a separate Component, the Components are grouped in a JPanel which is located near a corner of a JFrame which occupies most of the screen. The digits are updated by a dedicated Thread which loops with a 100ms wait(). When a digit changes it is repainted.</p>
  
  <p>The scheduling appears to be working: repaint() and paint() are called appropriately at 100ms intervals but the display is only updated every 500ms.</p>
  
  <p>However, if I move the mouse over the JFrame, or repeatedly press a key (control and shift both work) then the display updates faster.</p>
  
  <p>If I repaint the content pane of the JFrame every 100ms then the display updates correctly, but everything else in the JFrame is repainted unnecessarily. Repainting the portion of the JFrame that contains the time display has no apparent effect, but repainting a large area of the JFrame <em>which does not include the time display</em> does update the time.</p>
  
  <p>I have tried basing the digits on a JComponent and calling paintImmediately() (from the event dispatch thread) with no apparent difference.</p>
  
  <p>An explanation might be that the EDT waits with a 500ms timeout and is not being notified by paint(). Is there a way that I can explicitly notify the EDT to test this?</p>
  
  <p>I could probably work around this by displaying the time in a separate heavyweight container, but I would like to understand what is causing this behaviour.</p>
  
  <p>Here is a short program that produces this behaviour.
  With version 1.7 the line always rotates smoothly. With version 1.8 it moves smoothly at first but within two seconds it starts to jump. Note that the angle is incremented in the paint procedure, so if paints were being combined the line would still rotate smoothly but more slowly.</p>
  
  <p>I don't believe that it is necessary to call repaint from the EDT, but I have tried it and it makes no difference. The <em>for</em> loop does not run in the EDT, so the sleep is not blocking display updates.</p>
  
  <pre><code>    package bugs;
  
  import java.awt.Component;
  import java.awt.Dimension;
  import java.awt.Graphics;
  
  import javax.swing.JFrame;
  import javax.swing.SwingUtilities;
  
  public class DisplayRefresh {
      private class Cmpt extends Component {
          private static final int    POINTS = 16;
          int     m_ix;
  
          public Cmpt()
          {
              m_ix = 0;
          }
  
          public void paint(Graphics g)
          {
              Dimension sz = getSize();
              int rx = (sz.width - 1) / 2;
              int ry = (sz.height - 1) / 2;
              Double w = Math.PI * m_ix / POINTS;
              int x = (int)Math.floor(Math.sin(w) * rx);
              int y = (int)Math.floor(Math.cos(w) * ry);
              g.drawLine(rx - x, ry - y, rx + x, ry + y);
              m_ix = (m_ix + 1) % POINTS;
          }
      }
  
      JFrame      m_frame;
      Cmpt        m_cmpt;
  
      public static void main(String[] args) {
          (new DisplayRefresh()).exec();
      }
  
      private void exec()
      {
          m_frame = new JFrame();
          m_frame.setLayout(null);
          m_frame.setSize(600, 600);
          m_frame.setVisible(true);
          m_cmpt = new Cmpt();
          m_cmpt.setSize(64, 64);
          m_frame.add(m_cmpt);
          m_cmpt.setLocation(500, 100);
          if (SwingUtilities.isEventDispatchThread()) {
              System.out.println("This is the event dispatch thread");
          } else {
              System.out.println("This is NOT the event dispatch thread");
          }
          for (int i = 0; i &lt; 100; i++) {
              m_cmpt.repaint(10);
              try {
                  Thread.sleep(100);
              } catch(InterruptedException exc) {
                  System.out.println(exc.toString());
              }
          }
          m_frame.dispose();
          System.exit(0);
      }
  }
  </code></pre>