Skip to main content

Spring effects on buttons - now at your nearest look and feel

Posted by kirillcool on March 15, 2007 at 12:07 AM PDT

This is the third part in series about ghosting image (aka spring) effects on Swing buttons.

  • The first part introduced the "ghosting image" effects (aka "spring" in Romain presentations). When you rollover the mouse over a button, its icon has an outward decaying "ghost" image painted (starts from 50% opacity and decays linearly to zero).
  • The second part incorporated feedback from the readers, adding "spilling" the effects outside the button borders and adding the press animation.

Since then (last November) the implementation has been improved to provide the following:

  • The spilling effect is painted globally across the entire frame, including panels, toolbars, menubars, tabbed panes, desktop panes and title panes. It can also be easily extended to custom controls such as task pane container and status bar from SwingX.
  • The effects are available on JButtons and JToggleButton. They can also be easily extended to custom controls that have icons.

Last, but most certainly not the least, the implementation itself is no longer tied to Substance. It has been moved to the laf-widget project and has been successfully integrated with six other third-party look and feels. There are two ways to "inject" this functionality into the look and feel delegates (as promised in my presentation at Desktop Matters):

  • Java classes with main() methods that change existing binary UI delegates.
  • Ant tasks that change existing binary UI delegates.

The batch scripts in this CVS folder (look for augment-*.bat) show how an existing third-party LAF can be augmented with ghosting image effects. There are two separate classes, one injecting the functionality in icon-painting method in a specific UI delegate, and another injecting the spilling functionality in the update() method in a specific UI delegate.

The Ant tasks allow injecting this functionality at build time. Here is the relevant snippet from Substance build script:

   <taskdef name="icon-ghosting-augment" 
         classname="org.jvnet.lafwidget.ant.AugmentIconGhostingTask"
         classpath="${substance.lib.dir}/laf-widget.jar;${substance.lib.dir}/asm-all-2.2.2.jar" />
   <taskdef name="container-ghosting-augment"
         classname="org.jvnet.lafwidget.ant.AugmentContainerGhostingTask"
         classpath="${substance.lib.dir}/laf-widget.jar;${substance.lib.dir}/asm-all-2.2.2.jar" />

      <!-- Icon ghosting augmentation -->
      <icon-ghosting-augment verbose="true">
         <classpathset dir="${substance.output.dir}" />
         <iconghosting className="org.jvnet.substance.SubstanceButtonUI" methodName="paintIcon" />
         <iconghosting className="org.jvnet.substance.SubstanceToggleButtonUI" methodName="paintIcon" />
      </icon-ghosting-augment>

      <!-- Container ghosting augmentation -->
      <container-ghosting-augment verbose="true">
         <classpathset dir="${substance.output.dir}" />
         <containerghosting className="org.jvnet.substance.SubstanceDesktopPaneUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceMenuBarUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceMenuUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstancePanelUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceScrollBarUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceToolBarUI" toInjectAfterOriginal="true" />
      </container-ghosting-augment>

And now for some demonstrations. The following short videos show icon ghosting (rollover) and press ghosting effects on the same application under different look and feels. Note that for demo purposes i use larger icons and high-contrast implementation (high initial values for the fade out).

Here is how it looks under the InfoNode:

Here is how it looks under the Liquid:

Here is how it looks under the Looks PlasticXP:

Here is how it looks under the Napkin:

Here is how it looks under the Pagosoft:

Here is how it looks under the Squareness:

This technique will be presented at this year JavaOne conference at the "Bringing Life to Swing Applications" technical session that i have the honor to present with Alex Potochkin. Stay tuned for more and don't hesitate to leave comments.

Related Topics >>