Skip to main content

Animating layouts part I - the teaser

Posted by kirillcool on September 19, 2006 at 12:02 AM PDT

This is going to be the first part of a series about automatically animated layouts in Swing applications. The work on animation effects in Substance has begun a few months ago with the following design goals:

  • Make all animations on a single thread
  • Animate all Swing core components without any change to the application code
  • Make the animation as configurable as possible
  • Keep the animation overhead to the minimum

The animation layer originally written for Substance and later moved into the laf-widget project required minimal changes to provide animations on lists, tables and trees (by the way, i'm still waiting to hear how these can be done in timingframework), and hadn't to be changed a single bit in order to produce the following animated layouts (click on a green play button to start each one of the movies - i'm still learning how to use Wink properly):

Note that the movies show the SLOW animation kind - the default animation rate is twice as fast, and the animation itself can be turned off completely. There are no changes done between the two movies besides setting the layout on the main panel from Border to Flow. The layout animation itself is done with one single like in the application code. The animation rate in the real application is much more consistent than in the movie due to upload size constraints. Enjoy the next parts.

Here is the application code:

import java.awt.BorderLayout;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;



import javax.swing.*;



import org.jvnet.lafwidget.LafWidget;

import org.jvnet.lafwidget.layout.TransitionLayoutManager;

import org.jvnet.lafwidget.utils.LafConstants.AnimationKind;



public class SampleFrame extends JFrame {

  JButton b1, b2, b3;



  public SampleFrame() {

    super("Transition test");



    this.getContentPane().setLayout(new BorderLayout());



    JPanel buttons = new JPanel(new FlowLayout());

    this.getContentPane().add(buttons, BorderLayout.SOUTH);



    // for the first movie, change the following line to 

    // use the BorderLayout

    final JPanel mainPanel = new JPanel(new FlowLayout());

    // bring the magic in one single line

    TransitionLayoutManager.getInstance().track(mainPanel);

    this.b1 = new JButton("1");

    this.b2 = new JButton("2");

    this.b3 = new JButton("3");

    

    final JButton add = new JButton("add");

    add.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        SwingUtilities.invokeLater(new Runnable() {

          public void run() {

            mainPanel.add(b1, BorderLayout.WEST);

            mainPanel.add(b2, BorderLayout.CENTER);

            mainPanel.add(b3, BorderLayout.EAST);

            mainPanel.revalidate();

            add.setEnabled(false);

          }

        });

      }

    });

    buttons.add(add);



    this.getContentPane().add(mainPanel, BorderLayout.CENTER);



    final JCheckBox cb1 = new JCheckBox("1");

    cb1.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        b1.setVisible(!b1.isVisible());

        mainPanel.revalidate();

      }

    });

    buttons.add(cb1);



    final JCheckBox cb2 = new JCheckBox("2");

    cb2.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        b2.setVisible(!b2.isVisible());

        mainPanel.revalidate();

      }

    });

    buttons.add(cb2);



    final JCheckBox cb3 = new JCheckBox("3");

    cb3.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        b3.setVisible(!b3.isVisible());

        mainPanel.revalidate();

      }

    });

    buttons.add(cb3);



    final JCheckBox cb13 = new JCheckBox("13");

    cb13.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        b1.setVisible(!b1.isVisible());

        b3.setVisible(!b3.isVisible());

        mainPanel.revalidate();

      }

    });

    buttons.add(cb13);



    this.setSize(300100);

    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.setLocationRelativeTo(null);



    mainPanel.putClientProperty(LafWidget.ANIMATION_KIND,

        AnimationKind.SLOW);

  }



  public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {

      public void run() {

        new SampleFrame().setVisible(true);

      }

    });

  }

}
Related Topics >>