Tuesday, December 4, 2007

Timing Framework (part 2) - Triggers

In the last blog, I showed a simple demonstration of how the Timing Framework can help reduce the amount of boilerplate code required to code animations. In this entry I'll show how to use triggers to reduce this even further.

In the last entry we used code like this to start an animation when a button was clicked.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Animator anim = new Animator(2000, 5,
Animator.RepeatBehavior.REVERSE, new ButtonTimingTarget());
anim.setAcceleration(0.4f);
anim.setDeceleration(0.4f);
anim.start();
}
});
The Timing Framework provides triggers which extend the basic functionality of the framework. The framework provides a number of trigger classes which can trigger animations.

We can simplify the above code using an action trigger which corresponds to ActionEvents and so is perfect to use with a button. The trigger may be instantiated directly by client code but of more convenience is the static addTrigger method which also takes the object on which the trigger should operate.

For example, to add an action trigger to the button we'd do the following:
Animator anim = new Animator(2000, 5,
Animator.RepeatBehavior.REVERSE, new ButtonTimingTarget());
anim.setAcceleration(0.4f);
anim.setDeceleration(0.4f);

ActionTrigger.addTrigger(button, anim);
This may not seem like a huge reduction but it removes the boilerplate of the action listener implementation and removes the need for the anonymous inner class making the code arguably much more readable.

Currently the framework provides four trigger implementations:
  1. ActionTrigger - as shown above, may be used on any component that fires action events.
  2. FocusTrigger - may be used on components that fire focus events such as text fields
  3. MouseTrigger - may be used on components that fire mouse events (pretty much every component) such as when the mouse enters or leaves a component
  4. TimingTrigger - allows sequencing of different animations, for example starting an animation when another animation ends
The ActionTrigger is the simplest of the triggers and takes no special parameters. The more specialised triggers have a corresponding Event class (e.g. FocusTriggerEvent for the FocusTrigger or MouseTriggerEvent for the MouseTrigger) which specify the specific event(s) on which the trigger should operate. The key point is that the trigger class handles the setting of the listeners on the component to fire the animation at the appropriate time. All the developer needs to do is create the animation instance, set the trigger and let the framework ensure that the animation is fired appropriately.

Next time I'll take this a step further and use a property setter to simplify the code even more.

No comments: