title: Incremental graphics in Swing
body: <p>I'm trying to get the hang of doing graphics stuff (drawing lines,
  etc.) in Swing.  So far, all the tutorials I've seen declare a class
  that overrides <code>paintComponent</code>, and all the <code>paintComponent</code> methods
  do some set, specific thing, like drawing a red square (although maybe
  they draw it at a different location every time).  Or maybe they draw a number of lines and shapes, but the <code>paintComponent</code> method does everything all at once.</p>
  
  <p>I'm trying to figure out: suppose I want to draw one thing in a
  component, and later on draw something else on top of it without
  erasing what I drew before.  My first thought was to have my
  <code>paintComponent</code> override call a callback.</p>
  
  <pre><code>import java.awt.*;
  import javax.swing.*;
  public class DrawTest {
  
      private interface GraphicsAction {
          public void action (Graphics g);
      }
  
      private static class TestPanel extends JPanel {
  
          private GraphicsAction paintAction;
  
          public void draw (GraphicsAction action) {
              paintAction = action;
              repaint();
          }
  
          @Override
          public void paintComponent (Graphics g) {
              super.paintComponent (g);
              if (paintAction != null)
                  paintAction.action(g);
          }
      }
  
      private static void createAndShowGui() {
          JFrame frame = new JFrame ("DrawTest");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setPreferredSize(new Dimension(500,500));
  
          TestPanel p = new TestPanel ();
          frame.getContentPane().add(p);
          frame.pack();
          frame.setVisible(true);
          p.repaint();
  
          p.draw (new GraphicsAction () {
              public void action (Graphics g) {
                  g.setColor(Color.RED);
                  g.drawLine(5, 30, 100, 50);
              }
          });
  
          // in real life, we would do some other stuff and then
          // later something would want to add a blue line to the
          // diagram 
  
          p.draw (new GraphicsAction () {
              public void action (Graphics g) {
                  g.setColor(Color.BLUE);
                  g.drawLine(5, 30, 150, 40);
              }
          });
  
      }
  
      public static void main (String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  createAndShowGui();                 
              }
          });
      }
  }
  </code></pre>
  
  <p>This doesn't work.  A blue line shows up, but no red line.  I'm
  guessing this is because the <code>repaint()</code> in <code>draw</code> causes everything
  to start over when I draw the blue line, but I'm not sure; anyway, I don't know how else to get
  <code>paintComponent</code> to be called.</p>
  
  <p>Also, if I put a <code>Thread.sleep(1000)</code> between the two <code>p.draw</code> calls,
  I don't even see the red line for a second.  So I'm not at all clear
  on how to get my graphics to show up when I want them to.</p>
  
  <p>I've done some searching on "incremental graphics" in Swing, but
  nothing that helps find a solution.  I found an Oracle article
  "Painting in AWT and Swing" that discusses overriding an <code>update()</code>
  method to accomplish incremental graphics, but I haven't found any
  actual examples of this being done.</p>
  
  <p>So how would I get this to do what I want?  It seems like a common
  enough task that there should be a simple way to do it, but I haven't
  found one.  I'm assuming it should be doable without calling
  <code>getGraphics</code>, which, based on other StackOverflow responses would be,
  at best, kind of gauche.</p>