Friday, September 15, 2006

Animated Icon Redux

Lately we've been putting animated icons all over the UI to provide feedback about actions that are in progress. The spinning arrows are an animated GIF, while the spinning dial is dynamically generated with Java2D. Both icons are used just like any other icon (set and forget). No special coding is needed to get them to animate. This is how animated icons should behave.






The Icon interface's paintIcon method carries enough information for the icon to trigger its own repaint when it needs to display the next frame. Internally, the spinning arrows icon tracks the component on which it was painted as well as the location. Using this information, each time we want to display a new animation frame, we just walk the list of repaint locations and request a repaint on each of the stored items.

After testing this method out on a variety of components, I realized that this would be a superior method of animating icons in trees, tables, and lists (or any other component that makes use of CellRendererPane. With just a few tweaks, the logic was refactored to wrap animated GIF icons so that when they are used within a tree, table, or list, they are automatically refreshed as necessary. This is a much cleaner solution than the one I posted earlier.

I have a generic icon loader for my apps, so if the loader detects an animated GIF, it automatically wraps it in an AnimatedIcon and I don't have to worry about manually tracking animations.

Source

15 comments:

Anonymous said...

Do you have an rss feed link somewhere on this page?

Keep up the good work.

technomage said...

Here's the feed link:
http://rabbit-hole.blogspot.com/atom.xml

Anonymous said...

Thanks! I was very suprised that although there is a lot of code here, I can understand pretty much how it all bolts together. I'm particularly impressed with how you decorate the components - something I didn't know was possible without extending each class and overriding the paint methods.

I would like a similar fade + progress component in my GUI, but judging the fact that your source code contains copyright notices I assume I can't use it in a commercial application?

Although I would like to write this from scratch, I simply do not have the time to try to rewrite everything you have here - and my project only allows open source code. Here's hoping !!

Anonymous said...

Is the full source code avaliable? I notice that the jar file only contains three of the java files.

technomage said...

Source link is fixed. The last upload was missing some of the sources.

Anonymous said...

I try to compile your source code, but I don't know how to include the abbot library, The IDE I'm use is Java Studio Enterptrice 8, may I have your help?.

technomage said...

The abbot library is only required for the unit test code. It is available at http://abbot.sf.net.

Anonymous said...

Which classes are needed to run the Demo please? I looked in the repository but couldn't find a main class.
Your GUI effects are very aesthetic, nice.

technomage said...

Download the jar file from http://abbot.sf.net/demo/AnimatedIconDemo.jar, it has the sources in it.

Anonymous said...

Thanks technomage ( Cant see a way to pm you directly )

Daniel Schneller said...

Thank you very much for the spinning progress indicator, saved me the trouble of writing it myself. I really like the architecture with the Icon interface. Makes it very easy to integrate.

gumuruhsspj said...

hehehe... do u have the JButton with GIF animating inside the JTable example? Bcoz...
I used a custom JTable Render but giving a GIF not animating inside the JButton inside the JTable.

:(

Unknown said...

Hi,

very nice. Looks very good. But I have the same problem that I don't know how to use the AnimatedIcon in a JTable inside an CellRenderer.

An example would be useful.
Thanks.

Anonymous said...

Is there a way to import AnimatedIcon in a jar?

technomage said...

@Lukas You don't have to put it into a renderer, it only has to exist as a value produced by your table model.
@Anton, you can embed the class into your own jar file.