title: Graphics.drawImage from another Thread does not draw anything in Java Swing
body: <p>I'm trying to draw an animation in a <code>JPanel</code> by displaying all the frames as <code>BufferedImage</code> objects and using a <code>Thread</code> to invoke <code>g.drawImage</code> in the <code>JPanel</code>s <code>paintComponent(Graphics g)</code> method for each frame, with sleeping in between.  My understanding is that invoking <code>g.drawImage</code> from anywhere, as long as <code>g</code> is the <code>Graphics</code> object from the <code>paintComponent</code>, should cause the pixels in the <code>JPanel</code> to be updated, but there is no change in the <code>JPanel</code>.  Is that not how <code>Graphics.drawImage</code> works, or is it an issue with using another <code>Thread</code>, or something else all together?  An abbreviated version of my code is below, with unnecessary bits removed</p>
  
  <pre><code>class Example extends JPanel{
  
      public Dimension getPreferredSize(){
          return new Dimension(500, 500);
      }
  
      public void paintComponent(Graphics g){
          super.paintComponent(g);
          draw(g);
      }
  
      public void draw(Graphics g){
          BufferedImage temp1;
          BufferedImage temp2;
          try{
              temp1 = ImageIO.read(new File("C:\\Users\\Owner\\Desktop\\test1.png"));
              temp2 = ImageIO.read(new File("C:\\Users\\Owner\\Desktop\\test2.png"));
          }catch(IOException e){
              temp1 = null;
              temp2 = null;
          }
          final BufferedImage image1 = temp1;
          final BufferedImage image2 = temp2;
          Thread drawThread = new Thread(new Runnable(){
              public void run(){
                  g.drawImage(image1, 0, 0, null);
                  try{
                      Thread.sleep(100);
                  }catch(InterruptedException e){
                      // omitted
                  }
                  g.drawImage(image2, 0, 0, null);
                  try{
                      Thread.sleep(100);
                  }catch(InterruptedException e){
                      // omitted
                  }
              }
          });
          drawThread.start();
      }
  
      public static void main(String[] args){
          SwingUtilities.invokeLater(new Runnable(){
              public void run(){
                  JFrame frame = new JFrame();
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.add(new B());
                  frame.pack();
                  frame.setLocationRelativeTo(null);
                  frame.setVisible(true);
             }
          });
      }
  
  }
  </code></pre>