I have been working in a big program and one of its functionalities should be to print the contents of the main window. I checked the API and found this example:
http://docs.oracle.com/javase/tutorial/2d/printing/gui.html
it was very helpful, I tried to use that code in my program by placing this inside the actionperformed method of my print button:
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
If I click the print button, I get a printer dialog and when I tell it to print, it just prints a blank document. I know the above code is not all I need, as I've seen in the API's examples there is a print() method, but apparently they never call it, so it is pretty confusing. I've tried calling and using it many times, but with no success.
Also, I think that when I finally get it to print, my window will need to be printed in the landscape orientation, it even may need some scaling. Any ideas on how to do that?
I would like any useful help to help me implement this code successfully. I know I should be able to do it by myself just by checking the documentation (I've tried for almost 2 days now) but I can't get it to work. I've learned all the programming I know through the internet. Any help will be greatly appreciated.
The JFrame API. classes and include pack , setSize , show , hide , setVisible , setTitle , and getTitle . Much of the operation of a frame is managed by other objects. For example, the interior of a frame is managed by its root pane, and the content pane contains the frame's GUI.
Print JFrame with components coderanch.com print //Method called from Print Button public void FilePrintClicked(){ PrinterJob job = PrinterJob. getPrinterJob(); PageFormat format = job. defaultPage(); format.
A frame, implemented as an instance of the JFrame class, is a window that has decorations such as a border, a title, and supports button components that close or iconify the window. Applications with a GUI usually include at least one frame. Applets sometimes use frames, as well.
JFrame class inherits the java. awt. Frame class. JFrame is like the main window of the GUI application using swing.
Here's a simple solution. I have a Printer class that implements printable and it will handle the printing job:
public static class Printer implements Printable {
final Component comp;
public Printer(Component comp){
this.comp = comp;
}
@Override
public int print(Graphics g, PageFormat format, int page_index)
throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
// get the bounds of the component
Dimension dim = comp.getSize();
double cHeight = dim.getHeight();
double cWidth = dim.getWidth();
// get the bounds of the printable area
double pHeight = format.getImageableHeight();
double pWidth = format.getImageableWidth();
double pXStart = format.getImageableX();
double pYStart = format.getImageableY();
double xRatio = pWidth / cWidth;
double yRatio = pHeight / cHeight;
Graphics2D g2 = (Graphics2D) g;
g2.translate(pXStart, pYStart);
g2.scale(xRatio, yRatio);
comp.paint(g2);
return Printable.PAGE_EXISTS;
}
}
Next, to print it:
JFrame yourComponent = new JFrame();
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat preformat = pjob.defaultPage();
preformat.setOrientation(PageFormat.LANDSCAPE);
PageFormat postformat = pjob.pageDialog(preformat);
//If user does not hit cancel then print.
if (preformat != postformat) {
//Set print component
pjob.setPrintable(new Printer(yourComponent), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
Here's my twist on the idea...
Print to fit...
Print to fill...
public class TestPrinting {
public static void main(String[] args) {
try {
printComponentToFile(new PrintForm(), true);
printComponentToFile(new PrintForm(), false);
} catch (PrinterException exp) {
exp.printStackTrace();
}
}
public static void printComponent(JComponent comp, boolean fill) throws PrinterException {
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = pjob.defaultPage();
pf.setOrientation(PageFormat.LANDSCAPE);
PageFormat postformat = pjob.pageDialog(pf);
if (pf != postformat) {
//Set print component
pjob.setPrintable(new ComponentPrinter(comp, fill), postformat);
if (pjob.printDialog()) {
pjob.print();
}
}
}
public static void printComponentToFile(Component comp, boolean fill) throws PrinterException {
Paper paper = new Paper();
paper.setSize(8.3 * 72, 11.7 * 72);
paper.setImageableArea(18, 18, 559, 783);
PageFormat pf = new PageFormat();
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
BufferedImage img = new BufferedImage(
(int) Math.round(pf.getWidth()),
(int) Math.round(pf.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
ComponentPrinter cp = new ComponentPrinter(comp, fill);
try {
cp.print(g2d, pf, 0);
} finally {
g2d.dispose();
}
try {
ImageIO.write(img, "png", new File("Page-" + (fill ? "Filled" : "") + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ComponentPrinter implements Printable {
private Component comp;
private boolean fill;
public ComponentPrinter(Component comp, boolean fill) {
this.comp = comp;
this.fill = fill;
}
@Override
public int print(Graphics g, PageFormat format, int page_index) throws PrinterException {
if (page_index > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) g;
g2.translate(format.getImageableX(), format.getImageableY());
double width = (int) Math.floor(format.getImageableWidth());
double height = (int) Math.floor(format.getImageableHeight());
if (!fill) {
width = Math.min(width, comp.getPreferredSize().width);
height = Math.min(height, comp.getPreferredSize().height);
}
comp.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
if (comp.getParent() == null) {
comp.addNotify();
}
comp.validate();
comp.doLayout();
comp.printAll(g2);
if (comp.getParent() != null) {
comp.removeNotify();
}
return Printable.PAGE_EXISTS;
}
}
}
Some of the wider ranging issues...
addNotify
/validate
/doLayout
. Even when displayed on the screen, if you modify their bounds, you may need to call these methods.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With