title: Keep one painted object in a JPanel while painting another object (Java)
body: <p>I have a 9x9 grid that can paint itself, a rectangle that can paint itself, and a constructor that allows for movement of the rectangle with the arrow keys. However, I cannot figure out how to keep the grid on-screen at the same time the rectangle is moving around. Ultimately, I'll want the rectangle to be able to act as navigation of the grid by going right one square when the user presses right, etc.</p>
  
  <p>From what I can tell, the entire JPanel is redone whenever paint() is called, meaning that one way to do it would be to repaint every single line whenever a key is pressed, but that seems excessive. Any other way? As it is, painting the rectangle at all causes the grid to be painted over.</p>
  
  <pre><code>import java.awt.*;
  import java.awt.event.*;
  import javax.swing.*;
  
  
  public class TestDoubleObject extends JFrame
  {
  
      private Color ourRectColor = new Color(28,222,144);
      private int ourRectWidth = 50;
      private int ourRectHeight = 50;
  
      private Point ourRecLocation = new Point(150,150);
  
  
      public class Rectangle
      {
          protected void paint(Graphics2D g2d)
          {
                  g2d.setColor(ourRectColor);
                  g2d.fillRect(ourRecLocation.x, ourRecLocation.y, ourRectWidth, ourRectHeight);
          }
  
      } // Rectangle class
  
  
      public class OurRectangle extends JPanel
      {
  
          private Rectangle capableRectangle;
  
          public OurRectangle()
          {
              capableRectangle = new Rectangle();
          }
  
          @Override
          protected void paintComponent(Graphics g)
          {
              super.paintComponent(g);
              Graphics2D g2d = (Graphics2D)g.create();
  
              capableRectangle.paint(g2d);
  
              g2d.dispose();
          }
  
      } // OurRectangle class
  
  
      public class CoreGrid
      {
          protected void paint(Graphics2D g2d)
          {
  
              g2d.setColor(new Color(0,0,0));
  
              // Draw Horizontal Lines
  
              for(int i=100;i&lt;=640;i+=60)
                  g2d.drawLine(100,i,640,i);
  
  
              // Draw Vertical Lines
  
              for(int i=100;i&lt;=640;i+=60)
                  g2d.drawLine(i,100,i,640);
  
          }
  
      } // CoreGrid class
  
  
      public class OurCoreGrid extends JPanel
      {
          private CoreGrid capableCoreGrid;
  
          public OurCoreGrid()
          {
              capableCoreGrid = new CoreGrid();
          }
  
          @Override
          protected void paintComponent(Graphics g)
          {
              super.paintComponent(g);
              Graphics2D g2d = (Graphics2D)g.create();
  
              capableCoreGrid.paint(g2d);
  
              g2d.dispose();
          }
  
      } // OurCoreGrid class
  
  
      KeyStroke pressRight = KeyStroke.getKeyStroke("RIGHT");
      KeyStroke pressLeft = KeyStroke.getKeyStroke("LEFT");
      KeyStroke pressUp = KeyStroke.getKeyStroke("UP");
      KeyStroke pressDown = KeyStroke.getKeyStroke("DOWN");
  
      OurRectangle recToWorkWith = new OurRectangle();
      OurCoreGrid gridToWorkWith = new OurCoreGrid();
  
  
      public TestDoubleObject()
      {
  
          InputMap inputMap = recToWorkWith.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
          ActionMap actionMap = recToWorkWith.getActionMap();
  
  
          Action rightAction = new AbstractAction()
          {
              public void actionPerformed(ActionEvent e)
              {
                  ourRecLocation.x += 20;
                  recToWorkWith.repaint();
              }
          };
  
          inputMap.put(pressRight, "rightAction");
          actionMap.put("rightAction",rightAction);
  
  
          Action leftAction = new AbstractAction()
          {
              public void actionPerformed(ActionEvent e)
              {
                  ourRecLocation.x -= 20;
                  recToWorkWith.repaint();
              }
          };
  
          inputMap.put(pressLeft, "leftAction");
          actionMap.put("leftAction",leftAction);
  
  
          Action downAction = new AbstractAction()
          {
              public void actionPerformed(ActionEvent e)
              {
                  ourRecLocation.y += 20;
                  recToWorkWith.repaint();
              }
          };
  
          inputMap.put(pressDown, "downAction");
          actionMap.put("downAction",downAction);
  
  
          Action upAction = new AbstractAction()
          {
              public void actionPerformed(ActionEvent e)
              {
                  ourRecLocation.y -= 20;
                  recToWorkWith.repaint();
              }
          };
  
          inputMap.put(pressUp, "upAction");
          actionMap.put("upAction",upAction);
  
  
  
          add(gridToWorkWith);
  
          add(recToWorkWith);
  
  
  
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setSize(800,800);
          setVisible(true);
      }
  
      public static void main(String[] argv)
      {
          EventQueue.invokeLater(
  
          new Runnable()
          {
              @Override
              public void run()
              {
                  new TestDoubleObject();
              }
          });
      }
  }
  
  </code></pre>