title: How to save current state of graphics on JPanel
body: <p>I have a program that lets the user add rectangles and circles to JPanel using Graphics. What I want to be able to do is save the current state of the current JPanel (i.e. all of the shapes and their locations) into a file and be able to load that file back and restore that state. I have a Shapes class that extends JPanel and does all of the drawing and keeps track of the shapes with an ArrayList.</p>
  
  <p>Will I be able to just simply save the state of the panel? Or will I have to just save the Shapes data into a file and redraw the shapes when a file is "opened"?</p>
  
  <p>Can anyone guide me on how I can save the current state of my JPanel and re-open it? Thanks</p>
  
  <pre><code>public class UMLEditor {
  
      public static void main(String[] args) {
  
          JFrame frame = new UMLWindow();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setBounds(30, 30, 1000, 700);
          frame.getContentPane().setBackground(Color.white);
          frame.setVisible(true);
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
  
      }
  }
  
  class UMLWindow extends JFrame {
      Shapes shapeList = new Shapes();
  
      public UMLWindow() {
          addMenus();
      }
  
      public void addMenus() {
  
          getContentPane().add(shapeList);
  
          JMenuBar menubar = new JMenuBar();
          JMenu file = new JMenu("File");
          JMenuItem openMenuItem = new JMenuItem("Open File");
          openMenuItem.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent event) {
                  // Open saved state
          });
  
          JMenuItem saveMenuItem = new JMenuItem("Save");
          saveMenuItem.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent event) {
                  // Save current state
              }
          });
  
          file.add(openMenuItem);
          file.add(saveMenuItem);
  
          JMenu shapes = new JMenu("Shapes");
          file.setMnemonic(KeyEvent.VK_F);
  
          JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
          rectangleMenuItem.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent event) {
                  shapeList.addSquare(100, 100);
              }
          });
  
          JMenuItem circleMenuItem = new JMenuItem("New Circle");
          circleMenuItem.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent event) {
                  shapeList.addCircle(100, 100);
              }
          });
  
          shapes.add(rectangleMenuItem);
          shapes.add(circleMenuItem);
  
          menubar.add(file);
          menubar.add(shapes);
  
          setJMenuBar(menubar);
  
          setSize(300, 200);
          setLocationRelativeTo(null);
          setDefaultCloseOperation(EXIT_ON_CLOSE);
      }
  
  }
  
  // Shapes class, used to draw the shapes on the panel
  // as well as implements the MouseListener for dragging
  class Shapes extends JPanel {
      private static final long serialVersionUID = 1L;
  
      private List&lt;Path2D&gt; shapes = new ArrayList&lt;Path2D&gt;();
      int currentIndex;
  
      public Shapes() {
          MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
          addMouseListener(myMouseAdapter);
          addMouseMotionListener(myMouseAdapter);
      }
  
      public void addSquare(int width, int height) {
          Path2D rect2 = new Path2D.Double();
          rect2.append(new Rectangle(getWidth() / 2 - width / 2, getHeight() / 2
                  - height / 2, width, height), true);
  
          shapes.add(rect2);
          repaint();
  
      }
  
      public void addCircle(int width, int height) {
          Path2D rect2 = new Path2D.Double();
          rect2.append(new Ellipse2D.Double(getWidth() / 2 - width / 2,
                  getHeight() / 2 - height / 2, width, height), true);
  
          shapes.add(rect2);
          repaint();
      }
  
      @Override
      protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          this.setOpaque(true);
          this.setBackground(Color.WHITE);
          Graphics2D g2 = (Graphics2D) g;
          for (Path2D rect : shapes) {
              g2.draw(rect);
          }
      }
  
      class MyMouseAdapter extends MouseAdapter {
          private boolean pressed = false;
          private Point point;
  
          @Override
          public void mousePressed(MouseEvent e) {
              if (e.getButton() != MouseEvent.BUTTON1) {
                  return;
              }
              for (int i = 0; i &lt; shapes.size(); i++) {
                  if (shapes.get(i) != null
                          &amp;&amp; shapes.get(i).contains(e.getPoint())) {
                      currentIndex = i;
                      pressed = true;
                      this.point = e.getPoint();
                  }
              }
          }
  
          @Override
          public void mouseDragged(MouseEvent e) {
              if (pressed) {
                  int deltaX = e.getX() - point.x;
                  int deltaY = e.getY() - point.y;
                  shapes.get(currentIndex).transform(
                          AffineTransform.getTranslateInstance(deltaX, deltaY));
                  point = e.getPoint();
                  repaint();
              }
          }
  
          @Override
          public void mouseReleased(MouseEvent e) {
              pressed = false;
          }
      }
  }
  </code></pre>