Skip to main content

Trigger Happy

Posted by chet on May 26, 2006 at 11:55 AM PDT

Trigger Happy

I recently presented some slides on the
Timing Framework
 at JavaOne in the talk Filthy Rich Clients, to
show how to use this project to animate graphics and GUI applications (I was
joined by Ken Russell who showed some of the cool things you can do with
JOGL/Swing interaction in Mustang and Romain Guy, who showed how to use the
animation and JOGL stuff to make awesome GUI effects and applications).

As part of this, I described "Triggers", which are a recent addition to the
framework that I had not yet posted to the project site (it was a race to see
whether I would post it by the time JavaOne occurred, but that race was

I have now finished the work on Triggers (for now) and have posted the results
to the project site (along with a reorganization of the library and a couple of
new demos).  So I figured I'd better describe what Triggers actually do.

Triggers are a simple abstraction of event handling; they encapsulate
EventListener objects that your code would typically have to implement and
start or stop given animations based on events that you specify.  There's
not a lot of code there, but they should make your code a lot simpler.

The original intent of the Timing Framework was to make GUI animations much
simpler than they are in the current Java SE core libraries; setting up manual
Timer objects to run small animations on buttons is just so much work it's not
something you want to attack lightly.  So if the framework could embed all
of the tedious details like animation durations, non-linear acceleration,
setting values on properties automatically, and kicking off the animations
automatically, then maybe these effects could be more widely used.  As
part of that devious plan, I implemented Triggers to handle the
tedious-event-handling part of the equation.

Now, instead of setting up an EventListener subclass to handle a specific event
on a particular object (such as listening for a focus event on a Component),
you can set up a Trigger instead, which does the listening for you and starts
the animation that you tell it to based on the event.  But since you may
want to also stop an animation based on events (like stopping the
focus animation if the component loses focus), Triggers also allow you to
automatically stop an animation based on a specified event. 

Finally, there is a utility constructor that allows you to set up four related
actions based on a particular event.  Take the focus example; you might
want to animate up to some new look of a component based on focus.  But if
the component loses focus, you want to stop that animation.  So Triggers
make it easy to declare both a start action (based on an event) and a stop
action (based on the opposite event) for a particular animation/event
pair.  But you probably want to animate down from wherever you are instead
of just halting the animation abruptly.  So Triggers can be set to
automatically start/stop a different animation based on the opposite event
pair.  So if you lose focus, a losing-focus animation will start from the
point that you reached
automatically (and this losing-focus animation
will also stop automatically if the component gains focus in the meantime).

"From the point that you reached" is another important point to make
here; the recent changes to the framework allow "to" animations where a
property animates up to a declared value from whatever the value happens to be
at the start of the animation
.  In the case of the focus
animation, if the component loses focus while in the middle of animating up to
the focus value, then it will animate to a focus-lost value from the value in
the middle it had reached.  This is a new capability of PropertyRange (and
KeyValues underneath it) to allow value ranges of just one value, where it
assumes the first value will be assigned at the time the animation starts.

I could, and probably should, go into more detail on the API and have really
nice examples.  However, given all the stuff I have to catch up on after
JavaOne, I think I'll skip this crucial step and pull a typical engineer
response on you: "look at the code!"  But I can do one better than that at
least; check out the demo code.  Looking at the framework APIs (javadocs
and code) is great, but looking at the demos will show you how I actually
intended the stuff to be used.

Go to the project, check it
out, build it, look at the code.  Run the demos, look at their code. 
Let me know what you like and what you don't like.  There's more stuff to
come here, and I'd like to keep improving the framework to make it both more
useful and more easy for people to use.

Time to go...