hallorant

2 posts
hallorant

TimeUnit rocks! Blog

Posted by hallorant Oct 21, 2011

The java.util.concurrent library added a little gem of a class,TimeUnit, which is well worth knowing a bit about. The class is used in java.util.concurrent to inform time-based methods how a given timing parameter should be interpreted. This class, however, can breathe readability back into an API that would otherwise be tough to eyeball.

Consider an example from the Timing Frameworkproject.  In the API presented in the book Filthy Rich Clients (by Chet Haase and Romain Guy) you constructed an instance of an Animator as shown in the code snippet below:

animator = new Animator(10000, Animator.INFINITE, RepeatBehavior.LOOP);

This is a bit tough to understand without a bit of knowledge about the Animator constructor called. In fact, the first parameter is the time of the animation in milliseconds, the second parameter states that the animation should repeat forever (or until the animator is manually stopped), and the third parameter states that the animation should loop (the default repeat behavior is to reverse).

Today, using the current Timing Framework API, the snippet shown above would be changed to the code snippet below:

animator = new Animator.Builder()
  .setDuration(10000, TimeUnit.MILLISECONDS)
  .setRepeatCount(Animator.INFINITE)
  .setRepeatBehavior(RepeatBehavior.LOOP)
  .build();

My how things have changed!

First, the Builder pattern is used instead of (many) constructors. For more about this pattern (in Java) see Josh Bloch's Effective Java (second edition) Item 2: Consider a builder when faced with many constructor parameters. The use of the Builder helps to make it more obvious what each passed parameter is setting about the new Animator.

Second, the duration now has a value and units — we are using the TimeUnit class from java.util.concurrent to make it clear that value we are passing is intended to be a duration in milliseconds. Of course, now that we have TimeUnit we can write this duration a bit more clearly as 10 seconds, which most humans would intuit better than 10,000 milliseconds.

animator = new Animator.Builder()
  .setDuration(10, TimeUnit.SECONDS)
  .setRepeatCount(Animator.INFINITE)
  .setRepeatBehavior(RepeatBehavior.LOOP)
  .build();

This is great, if like me, you can change the API the library your using in your code (well, even I'm limited to only doing this for Timing Framework), but TimeUnit is so cool it can even help you out when the API doesn't use it. For example, I could use TimeUnit in the old TimingFramework API as shown below.

animator = new Animator(TimeUnit.MILLISECONDS.convert(10, TimeUnit.SECONDS), ...);

or

animator = new Animator(TimeUnit.SECONDS.toMillis(10), ...);

Here I'm using the built-in conversion abilities engineered into the TimeUnit class. The above two snippets are defined to be equivalent, so which one you prefer is up to you. Key here is that I get to use 10 seconds, which is the duration I'm thinking of, and the computer can convert this to what the API wants, a value in milliseconds. We avoid a human conversion which could be wrong.

TimeUnit really has helped calls to the Timing Framework API be easier to understand. It is also a great example of what can done with the enum type in the Java programming language. Finally, who wrote this little gem of a class? Doug Lea. Thanks Doug! (Update: Doug tells me that Tim Peierls also actively helped design TimeUnit. Thanks Tim!)TimeUnit is a cool little class that probably sould have been java.lang.TimeUnit — if only I could get that dang flux capacitor working in my DeLorean!

It's been several years since the book Filthy Rich Clients by Chet Haase and Romain Guy was published back in 2008. After reading the book I became a big fan of the Timing Framework that Chet posted at the timingframeworkproject at java.net. Chet had elegantly solved a tricky problem—controlling the timing of animations. But, woe is me, I developed Eclipse plug-ins and Chet's code was targeted for programmers who used Swing.

Wait, I thought, I could probably port this code to SWT. Then I could use it in my Eclipse work.

So that's exactly what I did. I checked out all the code from the timingframework project and started thetimingframework-swt project . The code I checked in to that project was a minimal port Chet's library to SWT.

Chet somehow noticed this project and emailed me. Couldn't we combine the two projects? he wondered. Maybe—but it was going to take some serious work that neither of us wanted to do. Chet and I talked again about this face-to-face at JavaOne 2009. Chet was giving a talk at JavaOne and he had uncovered a serious problem with the code's interaction with the Swing timer. A whole new approach to timing sources was needed. Chet moved to Adobe and I moved to SureLogic...time passed...

In early 2011 my attention again turned to Chet's Timing Framework due to work on a game called PlanetBaron. I dug in and began implementing the changes I had envisioned in 2009. I also uncovered a few bugs. I contacted Chet again, and to make a long story short, ended up administrating the Timing Framework project.

I immediately did three things:

  • I put out a classic 1.1 release with a few bug fixes for Chet's code (for folks reading Filthy Rich Clients).
  • I put out a 2.0 version with my API changes. There is aSwing and SWT release as well as a corerelease that contains shared non-GUI code.
  • I started going through the bugs reported by users over the last three years.
The last made me realize that I had a lot more work to do. So I dug back in and worked hard at the code, including adding a significant JUnit test suite to unit test the codebase. Version 3.0 was released on 13 April. (PlanetBaron is waiting!) 

I've started a Wiki to document the changes, but all of Chet's example programs from Filthy Rich Clients have been updated, and are now supported under Swing and SWT. The Javadoc is complete, and its overview explains how to run the demo programs.

The API is significantly different from that described inFilthy Rich Clients but the ideas of the original Timing Framework library still shine through—undimmed by my changes. I'll describe some of the changes, and the forces driving them, in future posts. But until then, head over to the timingframeworkproject at java.net and download the code, try out the cool demos, read the Wiki, and make your Swing or SWT applications "ooze cool."