0

I have made a Java program (JFrame based) using Netbeans, I would like to know if it is possible to print the layout of the program

I wish to have a button and set the function to "print" and the final layout of the frame will be printed, is it possible? If yes, any reference source?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Cross Bone
  • 11
  • 1
  • 3

3 Answers3

1

The simplest way is to use class Robot that can capture screen fragment at given coordinates. Take a look on this discussion: Java print screen program

Just send to robot the absolute coordinates of your JFrame

Community
  • 1
  • 1
AlexR
  • 114,158
  • 16
  • 130
  • 208
1

This will depend on what it is you hope to achieve.

You could simply print the contents of the frame to a BufferedImage. This allows you to control what you want to capture, in that you could print the content pane instead of the frame.

You could use Robot to capture the screen. This will capture what ever is on the screen at the location you are trying to capture, which might include more then just your frame...

"Print" vs "Capture"

enter image description hereenter image description here

import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PrintFrame {

    public static void main(String[] args) {
        new PrintFrame();
    }

    public PrintFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JLabel label = new JLabel("Clap if you're happy");

                final JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(label);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);

                InputMap im = label.getInputMap(JLabel.WHEN_IN_FOCUSED_WINDOW);
                ActionMap am = label.getActionMap();

                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_DOWN_MASK), "Print");
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK), "PrintAll");

                am.put("Print", new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            System.out.println("Print...");
                            BufferedImage img = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_ARGB);
                            Graphics2D g2d = img.createGraphics();
                            frame.printAll(g2d);
                            g2d.dispose();
                            ImageIO.write(img, "png", new File("Print.png"));
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                });
                am.put("PrintAll", new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            System.out.println("PrintAll...");
                            Robot bot = new Robot();
                            Rectangle bounds = frame.getBounds();
                            bounds.x -= 2;
                            bounds.y -= 2;
                            bounds.width += 4;
                            bounds.height += 4;
                            BufferedImage img = bot.createScreenCapture(bounds);
                            ImageIO.write(img, "png", new File("PrintAll.png"));
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                });

                frame.setVisible(true);

            }
        });
    }
}

Updated with better requirements

The basic requirement doesn't change a lot. You still need to capture the screen some how...

Here I've modified by "print" code to send the resulting BufferedImage to the printer. Note, I've done no checking to see if the image will actually fit, I'm sure you can work that out ;)

am.put("Print", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            System.out.println("Print...");
            BufferedImage img = new BufferedImage(frame.getWidth(), frame.getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = img.createGraphics();
            frame.printAll(g2d);
            g2d.dispose();
            PrinterJob pj = PrinterJob.getPrinterJob();
            pj.setPrintable(new FramePrintable(img));
            if (pj.printDialog()) {
                pj.print();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
});

Then, you simply need some way to actually render the contents to the printer...

public class FramePrintable implements Printable {

    private BufferedImage img;

    public FramePrintable(BufferedImage img) {
        this.img = img;
    }

    @Override
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {

        if (pageIndex == 0) {

            Graphics2D g2d = (Graphics2D) graphics;
            g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
            double x = (pageFormat.getImageableWidth() - img.getWidth()) / 2;
            double y = (pageFormat.getImageableHeight()- img.getHeight()) / 2;
            g2d.drawImage(img, (int)x, (int)y, null);

        }

        return pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE;
    }
}

This is pretty much take straight from the Printing trial...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Try taking a screenshot and save it to a file. Then you can print the file. The following code snippet can be used to take a screenshot :

boolean captureScreenShot()
{
      boolean isSuccesful = false;
      Rectangle screenRect = new Rectangle(0,0,500,500);//frame absolute coordinates
      BufferedImage capture;
      try {
          capture = new Robot().createScreenCapture(screenRect);
          // screen shot image will be save at given path with name "screen.jpeg"
          ImageIO.write(capture, "jpg", new File( "c:\\abc", "screen.jpeg"));
          isSuccesful = true;
      } catch (AWTException awte) {
          awte.printStackTrace();
          isSuccesful = false;
      }
      catch (IOException ioe) {
          ioe.printStackTrace();
          isSuccesful = false;
      }
      return isSuccesful;
}
Rishabh
  • 199
  • 3
  • 14
  • i mean its using printing to a printer, not printscreen – Cross Bone May 24 '13 at 06:26
  • "screen.png" contains the frame you want to print. You can now print this file ("screen.png") to the printer. Google it up. – Rishabh May 24 '13 at 06:29
  • then change the corodinates of the frame to exclude the window frame; as in give the coordinates as (0,10,500,500). – Rishabh May 24 '13 at 06:32
  • as in set the coordinates of the rectangle in such a way so as to include only the content of your frame! – Rishabh May 24 '13 at 06:35
  • 1
    @Rishabh Changing the rectangle by an arbitrary amount is not a good idea. Not all systems are equal. What happens if you are running a different OS or even the same OS with different font settings – MadProgrammer May 24 '13 at 06:42
  • yes, you're right. The above might be a temporary solution but will not work on different settings/resolutions! – Rishabh May 24 '13 at 06:45