Mark Stephens Mark has been working with Java and PDF since 1999 and is a big NetBeans fan. He enjoys speaking at conferences. He has an MA in Medieval History and a passion for reading.

Avoid transparency when printing in Java

1 min read

Java has a print mechanism called Java Print Services. In most cases this works brilliantly, but beware the use of transparency in anything you print! This article explains why this is and how you can tell if you have this issue.

Java Print Services allows you to add print capabilities to any Swing component (something it would be really nice to see in JavaFx if it wants to replace Swing). You just add a method like this to your Swing component

/**
* Implements the standard Java printing functionality.
*
* @param graphics the context into which the page is drawn
* @param pageFormat the size and orientation of the page being drawn
* @param page the zero based index of the page to be drawn
* @return int Printable.PAGE_EXISTS or Printable.NO_SUCH_PAGE
* @throws PrinterException
*/
public int print(Graphics graphics, PageFormat pageFormat, int page) throws PrinterException {

System.out.println(graphics);

System.out.println(“clip=” + graphics.getClipBounds());

//draw your component as you would in the paint() method – you can generally use the same code with the Graphics2D object

}

Like paint() it takes a Graphics2D object which we can draw on, providing a high level of abstraction and simplicity.

Let us run this on a 2 page test document containing some images as and see what we get.

sun.print.PeekGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
sun.print.PSPathGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
sun.print.PeekGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
sun.print.PSPathGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
All done

Java makes a dummy call to the print method to see what is there (PeekGraphics) and then makes ONE call to render the page onto the Graphics2D for the printer. So with 2 pages we have 4 calls in total.

Now I am going to make ONE change and see what happens with the same file….

sun.print.PeekGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
sun.print.PeekGraphics[]
clip=java.awt.Rectangle[x=0,y=0,width=612,height=792]
sun.print.ProxyGraphics2D[]
clip=java.awt.Rectangle[x=415,y=25,width=31,height=20]
sun.print.ProxyGraphics2D[]
clip=java.awt.Rectangle[x=500,y=25,width=71,height=19]

and so on for a long time!

So what did we change? In both cases, we used the same document. In the first case, we converted the images to BuffferedImage of time BINARY or GRAY while in the second, the BufferedImage ARGB. As soon as we have the possibility of any transparency on the page, Java Printing goes a bit mad and draws the page as a huge number of tiny blocks rather than in a single go. And performance drops off dramatically! Unfortunately, you often need transparency to display a PDF file correctly. So the trick is to try to minimise its usage.

So if you find you have performance issues in your print code, add in some debug code to your print() method and see if it is the dreaded transparency issue. Do you have any tips for print performance in Java?



Our software libraries allow you to

Convert PDF files to HTML
Use PDF Forms in a web browser
Convert PDF Documents to an image
Work with PDF Documents in Java
Read and write HEIC and other Image formats in Java
Mark Stephens Mark has been working with Java and PDF since 1999 and is a big NetBeans fan. He enjoys speaking at conferences. He has an MA in Medieval History and a passion for reading.

How to print PDF files from Java (Tutorial)

Printing PDF files from Java is something that raises a lot of general questions, so this short article is a general guide to the...
Mark Stephens
1 min read

Java PDF printing spool file size

Java Printing Services allows Java to provide printing in programs. JPS allows you to print some types of files directly. PDF is not a...
Mark Stephens
1 min read