1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.anim;
15  
16  import demo.view.DemoDefaults;
17  import y.anim.AnimationFactory;
18  import y.anim.AnimationObject;
19  import y.anim.AnimationPlayer;
20  import y.anim.CompositeAnimationObject;
21  import y.util.DefaultMutableValue2D;
22  import y.util.Value2D;
23  import y.view.Graph2D;
24  import y.view.Graph2DView;
25  import y.view.Graph2DViewRepaintManager;
26  import y.view.NodeRealizer;
27  import y.view.ViewAnimationFactory;
28  import javax.swing.JFrame;
29  import javax.swing.JPanel;
30  import javax.swing.JRootPane;
31  import javax.swing.Timer;
32  import java.awt.BorderLayout;
33  import java.awt.EventQueue;
34  import java.awt.event.ActionEvent;
35  import java.awt.event.ActionListener;
36  
37  /**
38   * Demonstrates usage and effects of ease in and/or ease out for animation
39   * effects.
40   *
41   * @see <a href="http://docs.yworks.com/yfiles/doc/developers-guide/animation.html">Section Animations for Graph Elements</a> in the yFiles for Java Developer's Guide
42   */
43  public class EaseInEaseOutDemo {
44    private static final int PREFERRED_DURATION = 2000;
45  
46    private final Graph2DView view;
47    private Value2D[][] positions;
48    private Timer timer;
49  
50    AnimationPlayer player;
51    ViewAnimationFactory factory;
52  
53    /**
54     * Creates a new EaseInEaseOutDemo and initializes a Timer that triggers the
55     * animation effects.
56     */
57    public EaseInEaseOutDemo() {
58      this.view = new Graph2DView();
59      DemoDefaults.configureDefaultRealizers(view);
60      init();    
61    }
62   
63    /**
64     * Initializes the start and end points for the animated movement effects.
65     * Creates nodes to demonstrate animated movement.
66     */
67    private void init() {
68      positions = new Value2D[4][2];
69      for (int i = 0, n = positions.length; i < n; ++i) {
70        positions[i][0] = DefaultMutableValue2D.create(70, 110 + i * 60);
71        positions[i][1] = DefaultMutableValue2D.create(410, 110 + i * 60);
72      }
73  
74      final String[] labels = {
75          "Normal", "Ease In", "Ease In, Ease Out", "Ease Out"
76      };
77  
78      final Graph2D graph = view.getGraph2D();
79  
80      for (int i = 0, n = positions.length; i < n; ++i) {
81        final Value2D pos = positions[i][0];
82        final NodeRealizer nr = graph.getRealizer(
83            graph.createNode(pos.getX(), pos.getY()));
84        nr.setSize(120, 30);
85        nr.setLabelText(labels[i]);
86      }
87  
88  
89      timer = new Timer(PREFERRED_DURATION + 500,
90          new ActionListener() {
91            private boolean invert;
92  
93            public void actionPerformed(final ActionEvent e) {
94              play(invert);
95              invert = !invert;
96            }
97          });
98      timer.setInitialDelay(1000);
99      timer.start();
100   }
101 
102   /**
103    * Plays the movement animation for the nodes in the graph.
104    * Four different kinds of movement animations are created:
105    * <ul>
106    * <li> normal (i.e. no ease effect) </li>
107    * <li> ease in </li>
108    * <li> ease in and ease out </li>
109    * <li> ease out </li>
110    * </ul>
111    *
112    * @param invert   if <code>true</code> the nodes move from right to left;
113    *                 otherwise the nodes move from left to right.
114    */
115   private void play(final boolean invert) {
116     final Graph2D graph = view.getGraph2D();
117 
118     if (factory == null) {
119       factory = new ViewAnimationFactory(new Graph2DViewRepaintManager(view));
120     }
121 
122     // we want to play all four animations at the same time
123     final CompositeAnimationObject moves = AnimationFactory.createConcurrency();
124 
125     for (int i = 0, n = positions.length; i < n; ++i) {
126       final Value2D dest = positions[i][invert ? 0 : 1];
127       final NodeRealizer nr = graph.getRealizer(graph.getNodeArray()[i]);
128 
129       // create a movement effect from the realizer's current position to
130       // the specified destination
131       AnimationObject move =
132           factory.move(nr, dest, ViewAnimationFactory.APPLY_EFFECT,
133               PREFERRED_DURATION);
134 
135       switch (i) {
136         case 1:
137           // create an ease in effect
138           move = AnimationFactory.createEasedAnimation(move, 1, 1);
139           break;
140         case 2:
141           // create an ease in and ease out effect
142           move = AnimationFactory.createEasedAnimation(move);
143           break;
144         case 3:
145           // create an ease out effect
146           move = AnimationFactory.createEasedAnimation(move, 0, 0);
147           break;
148       }
149 
150       // register the individual animations for concurrent processing
151       moves.addAnimation(move);
152     }
153 
154     if (player == null) {
155       player = factory.createConfiguredPlayer();
156     }
157     // play the animations
158     player.animate(moves);
159   }
160 
161 
162   /**
163    * Creates an application frame for this demo
164    * and displays it. The given string is the title of
165    * the displayed frame.
166    */
167   private void start(final String title) {
168     final JFrame frame = new JFrame(title);
169 
170     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
171     addContentTo(frame.getRootPane());
172     frame.pack();
173     frame.setLocationRelativeTo(null);
174     frame.setVisible(true);
175   }
176 
177   public final void addContentTo(final JRootPane rootPane) {
178     final JPanel contentPane = new JPanel(new BorderLayout());
179     contentPane.add(view, BorderLayout.CENTER);
180 
181     rootPane.setContentPane(contentPane);
182   }
183 
184   public void dispose() {
185     if (timer != null) {
186       if (timer.isRunning()) {
187         timer.stop();
188       }
189       timer = null;
190     }
191   }
192 
193   public static void main(String[] args) {
194     EventQueue.invokeLater(new Runnable() {
195       public void run() {
196         DemoDefaults.initLnF();
197         (new EaseInEaseOutDemo()).start("Ease Demo");
198       }
199     });
200   }
201 }
202