Avoid transparency when printing in Java

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?

This post is part of our “Printing Articles Index” in these articles, we aim to help you understand printing in Java and PDF’s.

Related Posts:

The following two tabs change content below.

Mark Stephens

System Architect and Lead Developer at IDRSolutions
Mark Stephens has been working with Java and PDF since 1999 and has diversified into HTML5, SVG and JavaFX. He also enjoys speaking at conferences and has been a Speaker at user groups, Business of Software, Seybold and JavaOne conferences. He has a very dry sense of humor and an MA in Medieval History for which he has not yet found a practical use.
Markee174

About Mark Stephens

Mark Stephens has been working with Java and PDF since 1999 and has diversified into HTML5, SVG and JavaFX.

He also enjoys speaking at conferences and has been a Speaker at user groups, Business of Software, Seybold and JavaOne conferences. He has a very dry sense of humor and an MA in Medieval History for which he has not yet found a practical use.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>