Create Moving Experiences with Animated Transitions Blog

Version 2


    Author's note and shameless plug: Animated Transitions, the general topic and the utility library, is explained in far more detail in Chapter 18 of the book Filthy Rich Clients. It seemed too much to ask to get everyone to buy the book just to see what this library was about, so this article was written to give an overview and introduction to the topic. If you like what you see, you should definitely check out the project on to see the code, the demos of Animated Transitions on the book's website, and maybe even the book itself for a more detailed explanation.

    A typical application has several states that it moves between during its lifetime: data entry forms, results screens, photo albums with different views of the images, shopping carts with items that you can't afford, and so on. Usually, applications do a horrible job of moving the user between these different screens: forms are erased before different forms take their place, results are popped suddenly onto the screen, and graphics and GUI objects jump discontinuously between screens. In general, each current UI screen is taken down when it's completed and then the new screen is displayed in its place.

    HTML applications are great examples of this: you fill out some data on one page, click the Submit button, watch it erase, and then wait for it to paint a completely new UI. Then you spend some time puzzling out the new interface, figuring out what you need to do, and where the new Submit button is.

    Wouldn't it be nice if applications created a more logical flow between these different application states, to gently bring the user with them into each new UI? What if users didn't have to figure out each new UI from scratch, but instead were brought along with the application so that they understood how they gothere from back there?

    That's what Animated Transitions are all about: animating the user interface from one screen of the application to the next, to create a seamless flow between these states. Transitions help keep the user connected to the program by helping them understand how the UIs fit together.

    The problem, of course, is that it means more work for the developer. Having the application erase one screen and display the next one is the most straightforward way to handle the situation. Running some kind of animation between the screens would usually entail actually understanding animation and then writing a pile of custom code to animate the elements on the screens.

    That's why the Animated Transitions library was written: it radically simplifies the process of animating between application states, performs reasonable default animations, and lets you concentrate on writing the application code, not the animation code.

    Demo Time

    Let's look at a simple demo application,FieldsOfText. This application mimics common functionality that you may have seen elsewhere, where the user can ask for the GUI to expand itself and provide more text fields. For example, I use a dialog box much like this when uploading critically important cartoons to my blog. The application starts with one text field, but clicking on the More or Less buttons will increase or decrease the number of text fields displayed.

    There is also a Submit button at the bottom because, well, because there's usually a Submit button in this type of application. The button doesn't actually do anything here, but it is there, like the other UI elements, to show off aspects of animated transitions.

    Here is the code that displays the GUI:

    // Add the More/Less buttons container add(moreOrLess); // Next, add the proper number of text fields for (int i = 0; i < numFields; ++i) { add(textFields[i]); } // Finally, add the Submit button at the bottom add(submitPanel);

    In this code, the moreOrLess component is a panel that holds the More and Less buttons. The textFields[]array holds the various text fields that are going to populate the GUI, and numFields is the number that we want to display at this time. The submitPanel component is a panel that holds the Submit button.

    Here's the basic UI that the user is first presented with:

    Initial screen of application
    Figure 1. Initial screen of application

    When the user clicks on the More button, a text field will be added below the existing one, resulting in the following screen:

    Second screen of application, after user clicks More button
    Figure 2. Second screen of application, after user clicks the More button

    When the user clicks on the Less button, the last text field goes away and the UI looks like it did in Figure 1.

    In a typical application, the window might erase in between these steps and then display the new UI. The Animated Transitions library instead moves smoothly between these states. It fades in or out components that are appearing or disappearing (e.g., a text field) and moves components that are in different positions (e.g., the Submit button). For example, Figure 2 shows what the UI looks like while the transition between the first and second screens is taking place:

    Animated transition between the first and second screens
    Figure 3. Animated transition between the first and second screens

    In Figure 3, we can see that the second text field is fading into view while the Submit button is moving down.

    If you'd really like to see the effect in action, I've created a short movie clip (QuickTimeor MPEG-4) showing the transition effect.

    Now, let's see how the demo application achieves this transition effect.

    Animated Transitions: The API

    At its most basic level, the library consists of aScreenTransition object, which is responsible for setting up and running the animation, and aTransitionTarget interface, which your code needs to implement.


    This object will be created by your code with parameters that set up the animation. The constructor looks like this:

    public void ScreenTransition(JComponent transitionContainer, TransitionTarget target, Animator animator)


    • transitionContainer is the container whose children will be animated during the transition.
    • target is an implementation ofTransitionTarget that defines the methodsetupNextScreen(), where the GUI for the screen to be transitioned to is defined.
    • animator defines the parameters of the actual animation, such as the duration. A full description ofAnimator is beyond the scope of this article. Check out the Timing Framework reference in the Resources section below for more information.

    To actually run the transition at any time from your application, you call the start() method:

    public void start()

    When this method is called, ScreenTransition will set up what it needs to in order to run the transition, and will then run the animation.


    TransitionTarget is a simple interface consisting of just one method:

    public void setupNextScreen()

    Your code needs to implement this method and set up the GUI of the transition container such that when the method is done, your application is in the state that you want it to be when the transition is complete.

    API Usage

    Let's see how this API is used by the FieldsOfTextapplication.

    First, we set up the Animator to run our transition animations for a half-second. We will also add some acceleration and deceleration at the beginning and end of the transition. This acceleration/deceleration behavior is not necessary, but non-linear movement makes for much better animations in general (as explained in the article " Smooth Moves").

    Animator animator = new Animator(500); animator.setAcceleration(.2f); animator.setDeceleration(.2f);

    We then set up the ScreenTransition object to use our main JComponent object as a container for the transition, that same object as the TransitionTargetwhere setupNextScreen() is implemented, and theanimator that we set up earlier:

    ScreenTransition transition = new ScreenTransition(this, this, animator);

    We trigger the transition when the user clicks either the More or Less button in the actionPerformed() method:

    public void actionPerformed(ActionEvent ae) { boolean changed = false; if (ae.getSource().equals(moreButton)) { if (numFields < MAX_FIELDS) { numFields++; changed = true; } } else if (ae.getSource().equals(lessButton)) { if (numFields > 1) { numFields--; changed = true; } } if (changed) { transition.start(); } }

    Finally, we handle the callback fromScreenTransition into our code in thesetupNextScreen() method:

    public void setupNextScreen() { // First, clear out the previous GUI and start from scratch removeAll(); // Add the More/Less buttons add(moreOrLess); // Next, add the proper number of text fields for (int i = 0; i < numFields; ++i) { add(textFields[i]); } // Finally, add the Submit button at the bottom add(submit); }

    Note that this is nearly the same code that we showed earlier when we described our GUI setup code; the only addition is that we first clear out the previous GUI with the call toremoveAll(); otherwise, all that this method does is set up the GUI for the appropriate screen of the application.

    And that's it! There is more code in the application to handle things like setting up the JFrame, drawing that cool blue gradient in the background, and setting up some details about the components and layout management, but most of the real logic of the application, particularly all of the code concerned with animated transitions, is listed above.

    So how does it actually work?

    How It Works

    When your code calls the start() method,ScreenTransition figures out the current attributes of the components in the transition container, such as their position and size. It then calls your setupNextScreen() method, where you set up the GUI for the next screen. Finally, it figures out the attributes for the components in this next screen that you have set up.

    Note that the system expects the transition container to share components when appropriate, not to have completely different components representing the same things. So, for example, if there is a Submit button in the previous screen and a Submit button in the next screen, you probably want to use the same actualJButton object in both cases to get the desired effect. Otherwise, the system will think that the previous button is going away and a new button is coming into being. There's no magic here; if you intend for components to be shared between screens, then you should use the same actual components in the screens.

    At this point, ScreenTransition has information on all of the components in both screens: which ones are in which screen, where they are, and how big they are. So it can figure out what changes will occur to each of these components between the two screens. Any component that changes between screens will undergo one of the following three transition types:

    • Appearing: The component is not in the first screen but is in the second.
    • Disappearing: The component is in the first screen but not in the second.
    • Changing: The component is in both screens, but changes between the screens.

    ScreenTransition will then pick an appropriate transition effect for each component:

    • Appearing: The component will fade in during the transition.
    • Disappearing: The component will fade out during the transition.
    • Changing: The component will move and scale as appropriate during the transition.

    Once it has all of this information,ScreenTransition will begin the animation, altering the appearance of each component during the animation according to the transition effect associated with that component.

    When the transition is complete, control is returned back to the application and the GUI previously set up by your application insetupNextScreen() is live.

    Custom Effects

    The built-in transition effects were created to handle the common cases that applications would generally want. Fading and moving/resizing the components is reasonable default behavior for typical situations. But applications that use Animated Transitions extensively might be interested in creating custom effects for particular components or situations. For example, maybe you want a disappearing component to zoom in or out, or to slide off the screen.

    The transition effects used by the library were written to be extensible so that you can plug in your own effects by creating the effects and registering them with the system. These effects are associated with both a component and transition type (appearing, disappearing, or changing). When ScreenTransitionsearches for an appropriate effect to use for any given component and transition type, it will use a custom effect if one has been registered.

    Writing a custom effect can be quite easy--you override just two or three methods to handle such functionality as setup, cleanup, and painting during the transition. Showing how to actually write a custom effect is beyond the scope of this brief article. But if you're interested in this feature, check out the demos for "Chapter 18: Animated Transitions" on the book's website, which show custom effects in code and action.

    Neat Tricks

    There are various techniques used in Animated Transitions in order to get the functionality and performance that the library needs. A full description of these techniques is more than we have space for here, but feel free to check out the code and the book for more details. For example, the way that the library handles setting up the second screen before the transition runs is interesting. Also, the way that the library deals with arbitrary layout managers in either or both screens is worth a look. And the way that the library takes image snapshots of components for fast display during the transition enables good performance while also enabling complex animations.

    Future Work

    The Animated Transitions library is a work in progress. I hope to continue refining the API and enhancing the functionality as time and experience march on. In the meantime, the library is quite useful at what it does and should provide developers the ability to easily and seamlessly connect different application states and provide a moving experience for their users.

    Try it out and let me know if it moves you.


    • The complete source code for the demo application described in this article.
    • Filthy Rich Clients: The site for the book, which describes this library in more detail (Chapter 18).
    • Animated Transitions: The project site for the library, with the full source code available and BSD-licensed.
    • Filthy Rich Clients demos: The project site for the demos in the book, which include two demos for Animated Transitions.
    • Timing Framework: The project site for the underlying animation library used by Animated Transitions.
    • My blog: I discuss related topics of graphics, animation, and desktop Java in general on this site.
    • " SmoothMoves": An article on that discusses various important elements in improving animation quality.
    • "How to Use the AnimatedTransition API (SwingX and Timingframework)": Nazmul Idris wrote this short tutorial explaining some of the basics for Animated Transitions and how he uses it in his work.
    • Aerith: This "Smashup" (Swing Mashup) application used an early version of the Animated Transitions code to achieve cross-fade transitions.