Java printing: creating PageFormat with minimal margin

I am trying to return the PageFormat value when printing. The following is an example of a program that shows my dilemma: I get a different result when I use printJob.setPrintable(printable) than when I use printJob.setPageable(book) when I create a Book object using the default PageFormat from the print job.

When I launched it and click "Print", then "Print using a book", I see this console output:

 doPrint(false) printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000 printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000 printing on 612.000000x792.000000 paper, imageable area=588.960000x768.960000 doPrint(true) printing on 612.000000x792.000000 paper, imageable area=468.000000x648.000000 printing on 612.000000x792.000000 paper, imageable area=468.000000x648.000000 

What gives? When using Book default page format sucks and uses 1 "edge" on each side of the page; for the "real" page format, only 1/6 "of the field on each side is required.

sample program here:

 package com.example.printing; import java.awt.BasicStroke; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.geom.Rectangle2D; import java.awt.print.Book; import java.awt.print.PageFormat; import java.awt.print.Paper; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import javax.swing.AbstractAction; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class PrintRectangles extends JFrame { static final int Nrectangles = 3; static class RectangleThingy extends JPanel implements Printable { @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { describePageFormat(pageFormat); if (pageIndex > 0) { return(NO_SUCH_PAGE); } else { Graphics2D g2d = (Graphics2D)graphics; g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); double w = pageFormat.getImageableWidth(); double h = pageFormat.getImageableHeight(); final int N = (Nrectangles - 1) / 2; final double spacing = 7.2; // 1/10 inch g2d.setStroke(new BasicStroke(0.1f)); for (int i = -N; i <= N; ++i) { double dx = i*spacing; Rectangle2D r = new Rectangle2D.Double( dx, dx, w-2*dx, h-2*dx ); g2d.draw(r); } Rectangle2D rthick = new Rectangle2D.Double( 0, 0, w, h ); g2d.setStroke(new BasicStroke(1.0f)); g2d.draw(rthick); return(PAGE_EXISTS); } } private void describePageFormat(PageFormat pageFormat) { System.out.println(String.format("printing on %fx%f paper, imageable area=%fx%f", pageFormat.getWidth(), pageFormat.getHeight(), pageFormat.getImageableWidth(), pageFormat.getImageableHeight() )); } } static private class PrintPreviewPanel extends JPanel { final private Printable p; final private PageFormat pageFormat; public PrintPreviewPanel(Printable p, PageFormat pf) { this.p = p; this.pageFormat = pf; } @Override public Dimension getPreferredSize() { return new Dimension((int)this.pageFormat.getWidth(), (int)this.pageFormat.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); try { p.print(g, this.pageFormat, 0); } catch (PrinterException e) { e.printStackTrace(); } } } public PrintRectangles(String title) { super(title); JPanel panel = new JPanel(); setContentPane(panel); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); JButton printButton = new JButton("Print"); JButton printUsingBookButton = new JButton("Print using Book"); JButton printPreviewButton = new JButton("Print preview"); panel.add(printButton); panel.add(printUsingBookButton); panel.add(printPreviewButton); printButton.addActionListener(new AbstractAction("print") { @Override public void actionPerformed(ActionEvent e) { doPrint(false); } }); printUsingBookButton.addActionListener(new AbstractAction("printUsingBook") { @Override public void actionPerformed(ActionEvent e) { doPrint(true); } }); printPreviewButton.addActionListener(new AbstractAction("printPreview") { @Override public void actionPerformed(ActionEvent e) { doPrintPreview(); } }); } protected void doPrint(boolean useBook) { RectangleThingy rectangleThingy = new RectangleThingy(); System.out.println("doPrint("+useBook+")"); try { PrinterJob printJob = PrinterJob.getPrinterJob(); PageFormat pageFormat = printJob.getPageFormat(null); if (useBook) { Book book = new Book(); book.append(rectangleThingy, pageFormat); printJob.setPageable(book); } else { printJob.setPrintable(rectangleThingy); } if (printJob.printDialog()) printJob.print(); } catch(PrinterException pe) { System.out.println("Error printing: " + pe); } } protected void doPrintPreview() { RectangleThingy rt = new RectangleThingy(); JFrame frame = new JFrame("print preview"); // hack for now -- how do we get this from the printer? Paper paper = new Paper(); double dotsperinch = 72; double margin = 0.125*dotsperinch; double w = 8.5*dotsperinch; double h = 11*dotsperinch; paper.setImageableArea(margin, margin, w-2*margin, h-2*margin); paper.setSize(w, h); PageFormat pfmt = new PageFormat(); pfmt.setPaper(paper); frame.setContentPane(new PrintPreviewPanel(rt, pfmt)); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new PrintRectangles("PrintRectangles").start(); } private void start() { setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); setVisible(true); } } 
+8
java printing
source share
1 answer

Hm. Having tried some fruitless efforts, it seems like setting the page to zero margin, and then calling PrinterJob.validatePage() seems to be the only way to get the actual minimum margin of PageFormat:

 static private PageFormat getMinimumMarginPageFormat(PrinterJob printJob) { PageFormat pf0 = printJob.defaultPage(); PageFormat pf1 = (PageFormat) pf0.clone(); Paper p = pf0.getPaper(); p.setImageableArea(0, 0,pf0.getWidth(), pf0.getHeight()); pf1.setPaper(p); PageFormat pf2 = printJob.validatePage(pf1); return pf2; } 

and then I can change doPrint() to:

 protected void doPrint(boolean useBook) { RectangleThingy rectangleThingy = new RectangleThingy(); System.out.println("doPrint("+useBook+")"); try { PrinterJob printJob = PrinterJob.getPrinterJob(); if (useBook) { Book book = new Book(); book.append(rectangleThingy, getMinimumMarginPageFormat(printJob)); printJob.setPageable(book); } else { printJob.setPrintable(rectangleThingy); } if (printJob.printDialog()) printJob.print(); } catch(PrinterException pe) { System.out.println("Error printing: " + pe); } } 
+17
source share

All Articles