Substance animation primer

November 29th, 2007

Lately, there have been quite a few postings on the mailing list of Substance look-and-feel that ask how to change the default animation settings. This can be required for a number of reasons, including performance speedup and proper effects on custom application renderers. Following in the footsteps of the painter primer and skinner primer, the animation primer provides the necessary information that you need to configure custom animation settings for Substance-powered applications.


To bring richer user experience to Swing applications, look-and-feels that use the Laf-Widget library can use its flexible and powerful animation layer. The layer provides support for animating core and custom Swing components, including core animations (such as rollovers and selections), as well as custom animations (such as pulsating border of a focused text component).While the default animation settings (which transitions to animate, the animation speed, the set of components to animate) were selected to provide a consistent and pleasant out-of-the-box visual experience with zero application configuration, some applications might need to configure the animation settings.There are three techniques that the applications can use to change the default animation settings:

  • <font color="darkblue">org.jvnet.lafwidget.animation.FadeConfigurationManager</font>
  • <font color="darkblue">org.jvnet.lafwidget.LafWidget.ANIMATION_KIND</font>
  • <font color="darkblue">META-INF/lafwidget.animations.properties</font>

Using the FadeConfigurationManager API

The <font color="darkblue">org.jvnet.lafwidget.animation.FadeConfigurationManager</font> is the first way to change the default animation settings. It provides the API to programmatically disable / enable core and custom animations. You can use the various <font color="darkblue">allowFades</font> and <font color="darkblue">disallowFades</font> on all controls, on all controls of the specified class or on a specific component. For example, here is how you can remove rollover and selection animations from the specific list:

JList list = ...; // create the list
FadeConfigurationManager.getInstance().disallowFades(FadeKind.ROLLOVER, list);
FadeConfigurationManager.getInstance().disallowFades(FadeKind.SELECTION, list);

where <font color="darkblue">org.jvnet.lafwidget.animation.FadeKind</font> is an instance of a core or custom animation kind.

Using the LafWidget.ANIMATION_KIND client property

The <font color="darkblue">org.jvnet.lafwidget.LafWidget.ANIMATION_KIND</font> is client property name for specifying the kind of animation on various components. The value should be one of <font color="darkblue">org.jvnet.lafwidget.utils.LafConstants.AnimationKind</font> enum. This property can be set either on component or globally on <font color="darkblue">UIManager</font>.

In order to compute the animation kind for some component, the component’s hierarchy is traversed bottom up. The first component that has this property set, defines the animation kind. Finally, if neither component not its ancestors define this property, the global setting on <font color="darkblue">UIManager</font> is checked. If there is no global setting, the default <font color="darkblue">LafConstants.AnimationKind.REGULAR</font> is taken.

The <font color="darkblue">LafConstants.AnimationKind.NONE</font> value can be used to remove all animations from the specific component (and its children) / globally. Here is how you can remove all the animations from a list:

List list = ...; // create the list
list.putClientProperty(LafWidget.ANIMATION_KIND, AnimationKind.NONE);

Using the META-INF/lafwidget.animations.properties resource file

The final way to configure the default animation settings is to bundle a <font color="darkblue">META-INF/lafwidget.animations.properties</font> text file with the application. Every line should be a fully qualified class name of a Swing component. At runtime, there will be no animations on a component if it is an instance of that class, an instance of class that is assignable from that class, or has a parent that matches the first two criteria.

Comparing the different techniques

There are different use cases for each one of the techniques.

  • The <font color="darkblue">FadeConfigurationManager</font> provides a powerful way to allow or disallow the specific animation kind. However, if you want to remove all animations globally or on the specific component, it is better to use <font color="darkblue">LafWidget.ANIMATION_KIND</font> set to <font color="darkblue">LafConstants.AnimationKind.NONE</font>.
  • If you want to configure the animation speed, you should use the <font color="darkblue">LafWidget.ANIMATION_KIND</font> and set it to either a core or a custom <font color="darkblue">LafConstants.AnimationKind</font>. A custom implementation can provide a non-linear cycle interpolation.
  • The <font color="darkblue">META-INF/lafwidget.animations.properties</font> should be used when you want to disable animations of all kinds on all instances of the specific components. In the core implementation, it is used to disable all animations from list, tree and table renderers.