Skip to main content

Animating layouts part V - layered / overlapping transitions

Posted by kirillcool on October 27, 2006 at 8:04 AM PDT

This is the fifth part in a series about automatically animated layouts in Swing applications.

  • The first part introduced the TransitionLayout. This part showed animated versions of BorderLayout and FlowLayout.
  • The second part showed the TransitionLayout applied to a (at least partially) real-world image viewer that allows live thumbnail resizing.
  • The third part described the current implementation and alternatives that were considered.
  • The fourth part showed a simple demo of an application that TransitionLayout installed on different containers.

With the release candidate of laf-widget version 2.0 (code-named Bluebottle) on October 30th (this Monday), i have started some more intensive testing of the TransitionLayout and (quite expectedly), i ran into quite a few visual issues. Some of them will be addressed in the next part (over this weekend), and the rest is discussed here.

First, you are welcome to read this thread on Java2D mailing list about compound composites on Graphics2D. As Chris points out, the best way to combine multiple composites is to create intermediate images. This is what i have been doing in Substance to support the transition fades (see the third part of this series for the reasons why). It works, but obviously it has some disadvantages. One would be that you are creating intermediate images which are later garbage collected, and another that the code becomes much more complicated and harder to read (especially a few weeks after you wrote it :). Going back to the issue at hand - the transition layout. Here is a scenario:

You have a tabbed pane with two panels. The first panel has some buttons, the second has some other controls (scroll down to see Flash movies). When you click some button in the first panel, it disappears (setVisible(false)) and some other controls appear instead. While they appear, you switch to the second panel. Now, if the TransitionLayout is installed on both the first panel and on the tabbed pane, the controls on the first panel (the disappearing button and the appearing controls) participate in two different transitions. The first transition is within the panel itself, and the second transition is the fade-out of the first panel when the tabbed pane is switched to the second panel. This means that the resulting composite of the controls on the first panel depend on multiple transitions that are happening at the same time.

Previously, this has not been taken into account. You would see two transitions "competing" over the same control - the visual result would be far from the expected (sudden changes in translucency in the middle of the fade cycles and so on). It was especially noticeable under slow animation speed (which can be set in the debug UI mode as described in this entry). These issues have been addressed in the latest drops of laf-widget and Substance and here are the examples.

This example shows tab switch to a panel that contains a button. While the button panel is fading in, the button is clicked, causing it to disappear and three other buttons to appear. There is a section when the three new buttons are fading in on top of the switched-off tab:

This example shows tab switch from a panel that contains a button. Before the button panel is fading out, the button is clicked, causing it to disappear and three other buttons to appear. There is a section when the three new buttons are fading in on top of the switched-on tab:

This example shows tab switch from a panel that contains six buttons. Before the tab switch is initiated, another button is clicked, causing two of the six buttons to disappear and other four to move (the original layout is FlowLayout). While the button panel is fading out, you can see the buttons disappear / move on top of the switched-on tab:

This example shows tab switch to a panel that contains five buttons. After the tab switch is initiated, another button is clicked, causing another (sixth) button to appear and other two to move (the original layout is FlowLayout). While the button panel is fading in, you can see the buttons disappear / move on top of the switched-off tab:

There is a new helper API in the TransitionLayout class targeted at look-and-feel delegates and custom application painting code. This API retrieves the opacity and the composite that should be used by the painting code in order to respect the currently executing (possibly multiple / overlaying) transition(s):

  /**

   * Returns the composite to use for painting the specified component. The

   * result should be set on the {@link Graphics2D} before any custom

   * rendering is done. This method can be used by application painting code

   * and by look-and-feel delegates.

   

   @param c

   *            Component.

   @return The composite to use for painting the specified component.

   */

  public static Composite getAlphaComposite(Component c)



  /**

   * Returns the composite to use for painting the specified component. The

   * result should be set on the {@link Graphics2D} before any custom

   * rendering is done. This method can be used by application painting code

   * and by look-and-feel delegates.

   

   @param c

   *            Component.

   @param translucency

   *            The translucency of the original painting (when the component

   *            is not under any transition fade effect).

   @return The composite to use for painting the specified component.

   */

  public static Composite getAlphaComposite(Component c, float translucency)



  /**

   * Returns indication whether the specified component is opaque. This method

   * can be used by look-and-feel delegates to decide whether the component

   * background should be filled. Use in conjunction with

   {@link #getAlphaComposite(Component)} or

   {@link #getAlphaComposite(Component, float)} to correctly fill the

   * component background during the transition fade animations. Note that

   * during the transition fades, the components are marked as non-opaque so

   * that Swing will handle them correctly. This means that calling

   {@link Component#isOpaque()} will return <code>false</code>,

   * incorrectly signifying to the painting code that the background fill

   * should be omitted.

   

   @param c

   *            Component.

   @return <code>true</code> if the specified component is opaque,

   *         <code>false</code> otherwise.

   */

  public static boolean isOpaque(Component c)

If your application doesn't have any custom painting code and you're running under the latest Substance, you don't have to change a single line in your code (except installing the TransitionLayout, obviously) to get the effects shown above. If you do have custom painting logic, all you need to do is to create a Graphics2D and set the appropriate composite:

  protected void paintComponent(Graphics g) {

    Graphics2D graphics = (Graphics2Dg.create();

    graphics.setComposite(TransitionLayout.getAlphaComposite(this));


Summing up - the new version of TransitionLayout handles cases like:

  • Component is fading in while its parent is fading out.
  • Component is fading out while its parent is fading in.
  • Component is fading in while its parent is fading in.
  • Component is fading out while its parent is fading out.

And not necessarily limited to two overlapping transitions. You're welcome to try it on your apps.

Related Topics >>