Friday, April 23, 2010

Open Source Java PDF Viewing Library Review

Here's a quick review of three open source Java based PDF libraries which can be used to view PDF documents in a Swing application. While there are some very good PDF generation libraries (iText and friends), there are fewer libraries which help render a PDF document into a type suitable for viewing in Swing.

JPedal
http://www.jpedal.org/

I've used JPedal in previous projects. It seems to work decently, but looking at the source code, the project is very disorganized and likely prone to bugs.

In my previous project, I had always exited my application by calling System.exit() or using the EXIT_ON_CLOSE parameter to the default close operation on a JFrame. It wasn't until playing with JPedal in a new project that I realized JPedal is hanging my swing app and preventing it from shutting down if my frames are simply disposed of. That is, if after having rendered a PDF document using JPedal, an application won't shutdown without having issued a System.exit().

I couldn't even find a single JPedal example where they used anything but System.exit(), so it seems they're probably aware of the problem and possibly hiding it? Don't know. I tried every combination I could find to cleanly close and dispose the JPedal resources to no avail. After looking at the source code, it doesn't necessarily surprise me.

I gave up on JPedal and was forced to move onto other choices.

PDF Renderer
https://pdf-renderer.dev.java.net/

This is/was a Sun sponsored open source project started by a few key Swing developers. I have met Richard Bair in person and he's a real great guy. So, this seemed like a logical next project to take a look at.

The API is by far the easiest to use. It's very simple to get a Swing based view of a PDF document up. However, the library currently only supports older PDF document versions. I have read that there is a patch available to allow rendering of new PDF. *bah* I was hoping for a solution that didn't require building the code myself. And, it somewhat looks like the project has stalled, which shouldn't be surprising given Sun's push on JavaFX and now Oracle.

Onto the next project.

Apache PDFBox
http://pdfbox.apache.org/

This turned out to be a good working solution. The API is a bit more confusing than the other two, and I couldn't seem to find an existing Swing component to render a PDF. But, the PDPage class of PDFBox has a convertToImage() method which returns a BufferedImage. So, it was fairly easy to take the generated image and draw onto the canvas of a JComponent.

My conversion code looks something like:
PDDocument doc = null;
try {
doc = PDDocument.load(inputStream);
final PDPage page = (PDPage) doc.getDocumentCatalog().getAllPages().get(0);

PipedInputStream pis = new PipedInputStream();
final PipedOutputStream pos = new PipedOutputStream(pis);

new Thread(new Runnable() {
@Override
public void run() {
try {
ImageIO.write(page.convertToImage(), "png", pos);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();

// create image panel
JPanel panel = new ImagePanel(pis);

} finally {
if (doc != null) {
doc.close();
}
}
My ImagePanel requires an InputStream (for reasons specific to the application), thus why the use of the I/O pipes. I also wish I knew a better way to get just the first page of the PDF document (without a call to getAllPage()), since this is all I was interested in (the application is generating a preview of the first PDF page).

PDFBox renders the newest PDF documents (from what I can tell), so this is good. Like I said, the API is a bit more difficult to learn, though it's now seemingly straight forward (as can be seen from the above). PDFBox is also in the Maven central repository, which is great for Maven development. All in all, I'm pretty happy with PDFBox.

jPodRenderer
http://opensource.intarsys.de/home/en/index.php?n=JPodRenderer.HomePage

I just found jPod tonight, having skipped over it a few times when searching. It actually looks pretty promising, especially since they have a specific renderer which will render to both AWT and SWT. So, that's cool. Looks like they have dependency on quite a few jars, though, and they don't seem to be in the central Maven repository, which stinks because of the dependencies. Anyway, if anyone has a review of jPod, send a link my way; I'd like to read about it.

Updated May 28th, 2010.
ICEpdf
http://www.icepdf.org/

Thanks to Mark Stephens at JPedal for providing this link. I wasn't aware of the project.

No comments:

Post a Comment