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:

  • org.jvnet.lafwidget.animation.FadeConfigurationManager
  • org.jvnet.lafwidget.LafWidget.ANIMATION_KIND
  • META-INF/lafwidget.animations.properties

Using the FadeConfigurationManager API

The org.jvnet.lafwidget.animation.FadeConfigurationManager 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 allowFades and disallowFades 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 org.jvnet.lafwidget.animation.FadeKind is an instance of a core or custom animation kind.

Using the LafWidget.ANIMATION_KIND client property

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

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 UIManager is checked. If there is no global setting, the default LafConstants.AnimationKind.REGULAR is taken.

The LafConstants.AnimationKind.NONE 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 META-INF/lafwidget.animations.properties 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 FadeConfigurationManager 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 LafWidget.ANIMATION_KIND set to LafConstants.AnimationKind.NONE.
  • If you want to configure the animation speed, you should use the LafWidget.ANIMATION_KIND and set it to either a core or a custom LafConstants.AnimationKind. A custom implementation can provide a non-linear cycle interpolation.
  • The META-INF/lafwidget.animations.properties 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.