title: Paint a JPanel to a BufferedImage or Print it without rendering it to screen first
body: <p>Picture this... A program GUI JFrame that is split in 2, EAST and WEST. The first JPanel is just a print preview screen. The EAST side of the JFrame is where the user can create a 1 2 or 3 size image. The user clicks the "Add" button and the defined image on the right goes to the panel on the left. So if the user clicks "Add" 3 times with different size images, then the panel uses FlowLayout to organize the added panel images added on the left.</p>
  
  <p>When you run this code, you can see a sorta idea of what I want. Really what would be nice is to create all this off-screen and call it MainPanel. Then have printPreview extend MainPanel and scale it down for screen view. And have the Printable method paint the MainPanel into the print method which would be a correct size.</p>
  
  <p>So my question...
  -Can you copy or paint a JPanel before it is rendered on the screen? 
  -Is there a better way to do what I want, I FlowLayout solves what I want amazingly, so a JPanel seems to be the answer unless there is something I do not know of.</p>
  
  <p>Ok now that that is pictured. I have built some code that is about as SSCCE as I can get.</p>
  
  <p>Guys I have tried asking this question at New To Java forums and they just do not respond, I am not double posting on purpose, I completely rewrote this from scratch.</p>
  
  <pre><code>import javax.swing.*;
  import java.awt.*;
  import java.awt.image.*;
  import java.awt.print.*;
  import java.awt.event.*;
  
  public class PrintGrid extends JFrame {
  
      Paper paper = new Paper();
  
      PrintGrid() {
          super("Check out this grid panel");
          setSize(672, 750);
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  
  
  
          add(paper);
          setVisible(true);
  
      } // end PrintGrid constructor
  
  
  
      // **************************
      // ****** PAPER CLASS *******
      // **************************
      private class Paper extends JPanel {
  
          final int PAPER_X = 672, PAPER_Y = 975, UNIT = 12, DPI = 72;
          X1 x1a = new X1(), x1b = new X1(), x1c = new X1();
          X2 x2a = new X2(), x2b = new X2(), x2c = new X2();
          X3 x3a = new X3(), x3b = new X3(), x3c = new X3();
  
          Paper() {
              setPreferredSize(new Dimension(PAPER_X, PAPER_Y));
              setBackground(Color.GRAY);
              setLayout(new FlowLayout(FlowLayout.LEADING));
  
              //Users will manually add different sizes to this sheet.
              add(x1a);
              add(x2a);
              add(x3a);
              add(x1b);
              add(x1c);
              add(x2b);
              add(x3b);
          }
  
  
          // ******* Parent Class for GridUnits *******
          abstract class GridUnit extends JPanel {
  
              MouseListen ml = new MouseListen();
              float alpha = 1.0f;
  
              GridUnit() {
                  this.addMouseListener(ml);
              }
  
              public void paintComponent(Graphics g) {
                  super.paintComponent(g);
                  this.setBackground(Color.BLACK);
  
                  Graphics2D g2 = (Graphics2D) g;
                  g2.setComposite(makeComposite(alpha));
  
                  g.setColor(Color.WHITE);
                  g.drawRect(0, 0, this.getWidth()-1, this.getHeight()-1);
  
                  g.setColor(Color.darkGray);
                  g.fillRect(15, 15, this.getWidth()-30, this.getHeight()-30);
  
              } // end paintComponent.
  
              private AlphaComposite makeComposite(float alpha) {
                  int type = AlphaComposite.SRC_OVER;
                  return(AlphaComposite.getInstance(type, alpha));
              }
  
              void click() {
                  setVisible(false);
              }
              void entered() {
                  alpha = 0.8f;
                  repaint();
  
              }
              void exited() {
                  alpha = 1.0f;
                  repaint();
              }
  
              class MouseListen extends MouseAdapter {
                  public void mouseEntered(MouseEvent event) {
                      entered();
                  }
                  public void mouseExited(MouseEvent event) {
                      exited();
                  }
                  public void mousePressed(MouseEvent event) {
                      click();
                  }
              }
  
          } // end GridUnit class
  
          class X1 extends GridUnit {
              X1() {
                  setPreferredSize(new Dimension(UNIT*13, UNIT*18));
              }
          } // end X1 Class
  
          class X2 extends GridUnit {
              X2() {
                  setPreferredSize(new Dimension(UNIT*26, UNIT*18));
              }
          } // end X1 Class
  
          class X3 extends GridUnit {
              X3() {
                  setPreferredSize(new Dimension(UNIT*39, UNIT*18));
              }
          } // end X1 Class
  
      } // end Paper class.
  
  
  
      public static void main(String[] args) {
          new PrintGrid();
      } // end main method.
  
  } //  end PrintGrid class.
  </code></pre>