Mega Code Archive

 
Categories / Java / Swing Components
 

Component Transition Animation

import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import org.jdesktop.animation.timing.Animator; import org.jdesktop.animation.timing.interpolation.PropertySetter; import org.jdesktop.animation.transitions.Effect; import org.jdesktop.animation.transitions.EffectsManager; import org.jdesktop.animation.transitions.ScreenTransition; import org.jdesktop.animation.transitions.TransitionTarget; import org.jdesktop.animation.transitions.effects.CompositeEffect; import org.jdesktop.animation.transitions.effects.FadeIn; /*  * SearchTransition.java  *  * Created on May 3, 2007, 3:05 PM  *  * Copyright (c) 2007, Sun Microsystems, Inc  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  *   * Redistributions of source code must retain the above copyright  *     notice, this list of conditions and the following disclaimer.  *   * Redistributions in binary form must reproduce the above  *     copyright notice, this list of conditions and the following  *     disclaimer in the documentation and/or other materials provided  *     with the distribution.  *   * Neither the name of the TimingFramework project nor the names of its  *     contributors may be used to endorse or promote products derived  *     from this software without specific prior written permission.  *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */ /**  *  * @author Chet  */ public class SearchTransition extends JComponent implements TransitionTarget,          ActionListener {     //     // GUI components used in the application screens     //     JLabel instructions = new JLabel("Search and ye shall find...");     JLabel searchLabel = new JLabel("Search:");     JTextField searchField = new JTextField("");     JEditorPane results = new JEditorPane("text/html",             "<html><body><b>Dung Beetles</b>: An Ode<br/>" +             "My Life with <b>Dung Beetles</b><br/>" +             "<b>Beetle</b> Bailey Gets Latrine Duty<br/>" +             "Evolution's Oddities<br/>" +             "Society's Parasites<br/>" +             "You <b>Dung</b> Me Wrong: A Country Music History<br/>" +             "Ding, <b>Dung</b>, The Witch is Dead<br/>" +             "'To be or not to <b>beetle</b>'<br/>" +             "Gross Insects of the World<br/>" +             "Nature's Sanitation Engineers<br/>" +             "Why are they here?<br/>" +             "</body></html>");     JScrollPane scroller = new JScrollPane(results);     private static final int LABEL_W = 50;     private static final int LABEL_H = 20;     private static final int FIELD_W = 100;     private static final int FIELD_H = 20;     private static final int INSTRUCTIONS_W = 170;     private static final int INSTRUCTIONS_H = 20;     private static final int RESULTS_X = 30;          //     // Animation variables     //     Animator animator = new Animator(500);    // Animate for half-second     // Setup transition with:     //      "this" as the transition container     //      "this" as the TransitionTarget callback object     //      animator as the animator that drives the transition     ScreenTransition transition = new ScreenTransition(this,             this, animator);     private CompositeEffect moverFader = null;          //      // Misc other instance variables     //     private int currentScreen = 0;      // Which screen are we on?     private int prevHeight = -1;     Paint bgGradient = null;     int prevW, prevH;          /** Creates a new instance of SearchTransition */     public SearchTransition() {         results.setEditable(false);                  // Setup the animation parameters         animator.setAcceleration(.2f);  // Accelerate for first 20%         animator.setDeceleration(.4f);  // Decelerate for last 40%                  // Set this as the listener for entries in the search field         searchField.addActionListener(this);                  instructions.setFont(instructions.getFont().deriveFont(15f));     }          @Override     public void setBounds(int x, int y, int w, int h) {         super.setBounds(x, y, w, h);         if (w != prevW || h != prevH) {             // Setup GUI for current screen given new size of our container             setupNextScreen();             prevW = w;             prevH = h;         }     }          /**      * Arrange the GUI for the initial search screen.      */     private void setupSearchScreen() {         int instructionsX =  (getWidth() - INSTRUCTIONS_W) / 2;         int instructionsY = getHeight() / 4;         int searchX = (getWidth() - LABEL_W - FIELD_W - 10) / 2;         int searchY = instructionsY + INSTRUCTIONS_H + 20;         int fieldX = searchX + LABEL_W + 10;         int fieldY = searchY;         add(instructions);         add(searchLabel);         add(searchField);         instructions.setBounds(instructionsX, instructionsY,                  INSTRUCTIONS_W, INSTRUCTIONS_H);         searchLabel.setBounds(searchX, searchY, LABEL_W, LABEL_H);         searchField.setBounds(fieldX, fieldY, FIELD_W, FIELD_H);     }          /**      * Arrange the GUI for the results screen      */     public void setupResultsScreen() {         int searchX = getWidth() - LABEL_W - FIELD_W - RESULTS_X - 10;         int searchY = 10;         int fieldX = searchX + LABEL_W + 10;         int fieldY = searchY;         int resultsX = RESULTS_X;         int resultsY = searchY + LABEL_H + 20;         add(searchLabel);         add(searchField);         add(scroller);         searchLabel.setBounds(searchX, 10, LABEL_W, LABEL_H);         searchField.setBounds(fieldX, fieldY, FIELD_W, FIELD_H);         scroller.setBounds(resultsX, resultsY,                  getWidth() - (2 * resultsX), getHeight() - resultsY - 20);     }          /**      * Change the gradient and effect according to the new window size      */     private void setupBackgroundAndEffect() {         // init the background gradient according to current height         bgGradient = new GradientPaint(0, 0, Color.LIGHT_GRAY.brighter(),                  0, getHeight(), Color.DARK_GRAY.brighter());                  // Init resultsEffect with current component size info         MoveIn mover = new MoveIn(RESULTS_X, getHeight());         FadeIn fader = new FadeIn();         moverFader = new CompositeEffect(mover);         moverFader.addEffect(fader);         EffectsManager.setEffect(scroller, moverFader, EffectsManager.TransitionType.APPEARING);         prevHeight = getHeight();     }          /**      * Override of paintComponent() to draw the gradient background      */     @Override     protected void paintComponent(Graphics g) {         if (bgGradient == null || getHeight() != prevHeight) {             setupBackgroundAndEffect();         }         ((Graphics2D)g).setPaint(bgGradient);         g.fillRect(0, 0, getWidth(), getHeight());     }     /**      * TransitionTarget callback; clear current state and set up      * state for next screen      */     public void setupNextScreen() {         // Clear out current GUI state   removeAll();         switch (currentScreen) {             case 0:                 setupSearchScreen();                 break;             case 1:                 setupResultsScreen();                 break;             default:                 break;         }     }          // Handle user hitting Enter in the search field     public void actionPerformed(ActionEvent ae) {         if (moverFader == null || prevHeight != getHeight()) {             setupBackgroundAndEffect();         }         // Change currentScreen, used later in setupNextScreen() callback         currentScreen = (currentScreen == 0) ? 1 : 0;         transition.start();     }          private static void createAndShowGUI() {   JFrame f = new JFrame();   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   f.setSize(400, 300);   SearchTransition component = new SearchTransition();   f.add(component);   f.setVisible(true);     }     /**      * @param args the command line arguments      */     public static void main(String[] args) {         try {             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());         } catch (ClassNotFoundException ex) {             ex.printStackTrace();         } catch (InstantiationException ex) {             ex.printStackTrace();         } catch (IllegalAccessException ex) {             ex.printStackTrace();         } catch (UnsupportedLookAndFeelException ex) {             ex.printStackTrace();         }   Runnable doCreateAndShowGUI = new Runnable() {       public void run() {     createAndShowGUI();       }   };   SwingUtilities.invokeLater(doCreateAndShowGUI);     } } /**  * Custom effect: moves a component in to its end location  * from a specified starting point  */ class MoveIn extends Effect {          private Point startLocation = new Point();          public MoveIn(int x, int y) {         startLocation.x = x;         startLocation.y = y;     }     /**      * Handles setup of animation that will vary the location during the      * transition      */     @Override     public void init(Animator animator, Effect parentEffect) {         Effect targetEffect = (parentEffect == null) ? this : parentEffect;         PropertySetter ps;         ps = new PropertySetter(targetEffect, "location",                  startLocation, new Point(getEnd().getX(), getEnd().getY()));         animator.addTarget(ps);         super.init(animator, parentEffect);     } }                     Filthy-Rich-Clients-ComponentTransitionAnimation.zip( 138 k)