Writing a PDF Viewer in JavaFX 2.0

Back in 2009, I wrote a quick viewer based on JavaFX 1.2 and the LGPL version of our PDF library. Since JavaFX 2.0 has just been released, and has moved from being a scripting language to being a part of Java, I decided it would be interesting to do it all again and compare the process.

When working with JavaFX 1.2, my primary complaint was distribution. My complaint was that the only practical means of distribution was via WebStart. This is no longer true – deployment can follow any of Java’s standard patterns, although you must make sure your user has JavaFX installed. This is due to change from the release of Java 8, which will see JavaFX included as a core part of Java.

Swing

However, along with the good, there’s also the bad – earlier releases allowed for Swing components inclusion in scene graphs, which is no longer possible due to an entirely new graphics pipeline. On the bright side, while you can no longer embed Swing in JavaFX, you can now embed JavaFX in Swing.

The separation between Swing and JavaFX goes so far that BufferedImage cannot be used within JavaFX. It seems FX’s Image class only reads images in from the disk instead of allowing for conversion from BufferedImage, except a few methods for converting between the two which are distinctly not part of the API. Since the only other option is writing images to disk from Java2D and then reading them in again from JavaFX, they’re what we’re using for JPedalFX (for now).

Another issue I ran across was the lack of an easy way to produce a message dialog. Swing has JOptionPane, which is callable but causes freezes, but no such convenience has yet been added for JavaFX. Admittedly it doesn’t take a great deal of time to code one for yourself, but it certainly detracts from the convenience – and in an API based on a language designed to create interfaces fast, that’s a problem.

Styling and Animation

The new method of styling components uses CSS. This seems like a good idea to me, as most users should find the language and model used familiar. Despite this, I found it surprisingly hard to put a black border around the application, as you cannot style a Stage and styling the topmost component produces unpredictable results. I ended up changing a lot of components positions or sizes by one or two pixels to get the border to display.

In fact, a lot of the nice benefits given to components would be nice on Stages – the Timeline/Transition system works very well for animating positions, opacities, scaling and sizes of components, while only opacity is available on Stages. It’s possible to achieve similar functionality by using the AnimationTimer class, which has a method which is called after each frame is rendered. I used this for the fade and zoom out animation when closing the viewer, which works but is somewhat jittery.

Conclusion

Because it’s changed so much, and there is still so much ahead to do, it feels in many ways more like a 0.8 release than a 2.0. Full release integration with Java across all platforms, proper support for BufferedImages, a counterpart to Swing’s JOptionPane and better mouse support (including Multi Touch support) are all scheduled features which should make JavaFX feel more like a full release than a beta. I have no doubt JavaFX will be a great step forward for Java – I’m just not quite sure it’s there yet.

Related Posts:

The following two tabs change content below.
Sam is a developer at IDRsolutions who mostly specialises in font support and conversion. He's also enjoyed working with Java 3D, Java FX and Swing. His other interests include music and game design.
SamH

About Sam Howard

Sam is a developer at IDRsolutions who mostly specialises in font support and conversion. He’s also enjoyed working with Java 3D, Java FX and Swing. His other interests include music and game design.

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>