Reputation: 11
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?
Upvotes: 0
Views: 843
Reputation: 347194
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"
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...
Upvotes: 1
Reputation: 199
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;
}
Upvotes: 0
Reputation: 115328
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
Upvotes: 1