Converting a Swing application into JavaFX – Listeners and fast scrolling

Recently, I have been working on producing a JavaFX implementation of the Swing PDF Viewer in our JPedal PDF library. This has involved a large amount of refactoring to separate out common, shared code and then implementing JavaFX specific functions or optimisations.

One of the features which we make extensive use of in our PDF viewer is listeners. When you scroll inside a PDF file, Java is not fast enough to decode every page in real time as you scroll through the PDF document if you just want to scroll very quickly. If we did this, some documents would be fine but some would be very sluggish and slow. As they scroll, we display the page borders with a white background.We wait for the user to stop scrolling and as soon as they pause, we will decode the visible pages.

Top of PDF document

Fast scroll through the document

Bottom of PDF document

If the user open the PDF viewer at the top of the document and then scrolls down to the bottom quickly, we would just decode the top few pages and the bottom few.

Tracking when the user stops is an interesting problem. There are lots of ways to track that the user is moving or components being resized but no real user has stopped event. It is a negative event.  So when the user first starts scrolling, we will start a timer and every time the user scrolls again we restart the timer. The timer will only ever execute once there is a pause (which is the event we want to track).

In Swing we have a JPanel as our base class, so we add a Listener to this with the standard addComponentListener(viewListener) method. Here is our implementation for viewListener class (RefreshLayout) which extends ComponentAdapter.

private class RefreshLayout extends ComponentAdapter {
 
        //our timer which will trigger event if it finished executing
        //we keep restarting it on each move
        PageMoveTracker tracker=new PageMoveTracker();
 
        @Override
        public void componentMoved(final ComponentEvent e) {
 
            //will restart if running
            tracker.startTimer(pages,getPageNumber(),fileAccess); 
        }
 
        @Override
        public void componentResized(final ComponentEvent e) {
 
            //will restart if running
            tracker.startTimer(pages,getPageNumber(),fileAccess);
        }
 
        public void dispose() {
            tracker.dispose();
        }
    }

 

JavaFX has far more flexibility in terms of Listeners and lets you neatly bind listeners onto properties. We are using the same Timer object to track when the user stops scrolling, but this time we attach it to the ScrollPane we display and we implement ChangeListener.

ourScrollPane.viewportBoundsProperty().addListener(viewListener);         
ourScrollPane.vvalueProperty().addListener(viewListener);
ourScrollPane.hvalueProperty().addListener(viewListener);
 
class RefreshLayout implements ChangeListener {
 
        PageMoveTracker tracker=new PageMoveTracker();
 
        public void dispose() {
            tracker.dispose();
        }
 
        @Override
        public void changed(ObservableValue ov, Object t, Object t1) {
 
            tracker.startTimer(pages, getPageNumber(), fileAccess);
        }
    }

This gives us the same functionality in both Swing and JavaFX for our two Java PDF viewers.

We are currently looking at writing a series of articles on converting a Swing Application into JavaFX, so if you found this article of interest and would like to see more, please let us know. Or let us have your suggestions and tips on conversion as comments on the article!

If you’re a first-time reader, or simply want to be notified when we post new articles and updates, you can keep up to date by social media (TwitterFacebook and Google+) or the Blog RSS.

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>