~ubuntu-branches/ubuntu/trusty/mediathekview/trusty

« back to all changes in this revision

Viewing changes to src/net/sf/jcarrierpigeon/Notification.java

  • Committer: Package Import Robot
  • Author(s): Markus Koschany
  • Date: 2014-01-07 17:25:52 UTC
  • mfrom: (4.1.6 sid)
  • Revision ID: package-import@ubuntu.com-20140107172552-vkv6uixpou3sa5og
Tags: 4-1
* Imported Upstream version 4.
* Declare compliance with Standards-Version 3.9.5.
* Correct a mistake in the last changelog entry.
  - build-dependencies <-> dependencies
* Override lintian warning:incompatible-java-bytecode-format Java7 because
  Java7 is the current default JRE for Jessie. MediathekView also requires
  Java7 to run and is incompatible with Java6 or earlier.
* debian/control: Add libjackson2-core-java, libtimingframework-java and
  libxz-java to Build-Depends-Indep.
* Drop README.source. Now upstream provides a source tarball.
* Refresh modify-ant-build-system.patch.
* debian/rules: Remove get-orig-source target. No longer needed.
* Update mediathekview.manifest. Add new required libraries to classpath.
* Update debian/watch for new versioning scheme.
* Update debian/copyright for new release. Add BSD-3-clause license.
* Update man pages and remove unsupported options.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * \cond LICENSE
 
3
 * ********************************************************************
 
4
 * This is a conditional block for preventing the DoxyGen documentation
 
5
 * tool to include this license header within the description of each
 
6
 * source code file. If you want to include this block, please define
 
7
 * the LICENSE parameter into the provided DoxyFile.
 
8
 * ********************************************************************
 
9
 *
 
10
 * JCarrierPigeon - A notification library
 
11
 * Copyright (c) 2010, Paulo Roberto Massa Cereda
 
12
 * All rights reserved.
 
13
 *
 
14
 * Redistribution and use in source and binary forms, with or
 
15
 * without modification, are permitted provided that the following
 
16
 * conditions are met:
 
17
 *
 
18
 * 1. Redistributions of source code must retain the above copyright
 
19
 *    notice, this list of conditions and the following disclaimer.
 
20
 *
 
21
 * 2. Redistributions in binary form must reproduce the above copyright
 
22
 *    notice, this list of conditions and the following disclaimer in
 
23
 *    the documentation and/or other materials provided with the
 
24
 *    distribution.
 
25
 *
 
26
 * 3. Neither the name of the project's author nor the names of its
 
27
 *    contributors may be used to endorse or promote products derived
 
28
 *    from this software without specific prior written permission.
 
29
 *
 
30
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
31
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
32
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
33
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
34
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
35
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
36
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 
37
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
38
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 
39
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 
40
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
41
 *
 
42
 * ********************************************************************
 
43
 * End of the LICENSE conditional block
 
44
 * ********************************************************************
 
45
 * \endcond
 
46
 *
 
47
 * <b>Notification.java</b>: provides the notification features to any
 
48
 * <code>javax.swing.JFrame</code> or <code>javax.swing.JWindow</code>
 
49
 * object. Please note that this new class introduced in version 1.3 is
 
50
 * the new replacement for <b>net.sf.jcarrierpigeon.CarrierPigeon</b>,
 
51
 * assigned as deprecated.
 
52
 */
 
53
 
 
54
package net.sf.jcarrierpigeon;
 
55
 
 
56
import java.awt.GraphicsEnvironment;
 
57
import java.awt.Rectangle;
 
58
import javax.swing.JFrame;
 
59
import javax.swing.JWindow;
 
60
import org.jdesktop.animation.timing.Animator;
 
61
import org.jdesktop.animation.timing.TimingTarget;
 
62
 
 
63
/**
 
64
 * Provides the notification features to any <code>javax.swing.JFrame</code>
 
65
 * or <code>javax.swing.JWindow</code> object. In order to achieve a greater
 
66
 * effect, it's highly recommended to remove the window border of the provided
 
67
 * <code>javax.swing.JFrame</code>. You don't need to worry with that when
 
68
 * using <code>javax.swing.JWindow</code>, since it has no borders at all.
 
69
 * Please note that this new class introduced in version 1.3 is the new
 
70
 * replacement for <b>net.sf.jcarrierpigeon.CarrierPigeon</b>, assigned
 
71
 * as deprecated. If you are using  <b>net.sf.jcarrierpigeon.CarrierPigeon</b>,
 
72
 * please change your code to use this class together with the new
 
73
 * <b>net.sf.jcarrierpigeon.NotificationQueue</b>. Check the following example:
 
74
 * @code
 
75
 * JWindow window = new JWindow();
 
76
 * Notification note = new Notification(window, WindowPosition.BOTTOMRIGHT, 25, 25, 1000);
 
77
 * NotificationQueue queue = new NotificationQueue();
 
78
 * queue.add(note);
 
79
 * @endcode
 
80
 * Note that <b>net.sf.jcarrierpigeon.Notification</b> takes the very same
 
81
 * parameters of the deprecated <b>net.sf.jcarrierpigeon.CarrierPigeon</b>
 
82
 * class. Aside from the addition of <b>net.sf.jcarrierpigeon.NotificationQueue</b>,
 
83
 * there is not so much change in code.
 
84
 * 
 
85
 * @author Paulo Roberto Massa Cereda
 
86
 * @version 1.3
 
87
 * @since 1.3
 
88
 */
 
89
public class Notification implements TimingTarget {
 
90
 
 
91
    private WindowPosition windowPosition;
 
92
    private WindowType windowType;
 
93
    private int thisHeight;
 
94
    private int thisWidth;
 
95
    // window object
 
96
    private JFrame windowJFrame;
 
97
    private JWindow windowJWindow;
 
98
    // coordinates
 
99
    private double borderX, borderY;
 
100
    private double boundX, boundY;
 
101
    private double positionX, positionY;
 
102
    // animation control
 
103
    private int duration;
 
104
    private AnimationFrame animationFrame;
 
105
    // animators, each one representing one state
 
106
    // on AnimationFrame class
 
107
    private Animator animatorHandlerOnShow;
 
108
    private Animator animatorHandlerOnDisplay;
 
109
    private Animator animatorHandlerOnClose;
 
110
    // time in milliseconds to animate windows
 
111
    // on show and close events
 
112
    private int timeToAnimate = 500;
 
113
 
 
114
    /**
 
115
     * Constructor method for a basic <code>javax.swing.JFrame</code> object.
 
116
     * It basically builds the notification model according to the provided
 
117
     * parameters. Just keep in mind the provided <code>javax.swing.JFrame</code>
 
118
     * is <b>disposed</b> after the notification being displayed. Check the
 
119
     * following example:
 
120
     * @code
 
121
     * JFrame window = new JFrame();
 
122
     * Notification note = new Notification(window, WindowPosition.BOTTOMRIGHT, 25, 25, 1000);
 
123
     * NotificationQueue queue = new NotificationQueue();
 
124
     * queue.add(note);
 
125
     * @endcode
 
126
     * @param window The window to act as a notification. Please, remove the borders
 
127
     * in order to achieve a greater effect.
 
128
     * @param windowPosition The window position on screen. You may choose one amongst
 
129
     * four states, each one representing the screen corners.
 
130
     * @param borderX The distance in pixels the window must keep from the X axis border. If
 
131
     * the notification is right-aligned, this border will be from the right side, and so forth.
 
132
     * Usually 50 pixels or less is an acceptable value for this parameter.
 
133
     * @param borderY The distance in pixels the window must keep from the Y axis border. If
 
134
     * the notification is aligned from the top, this border will be from the top itself, and so forth.
 
135
     * Usually 50 pixels or less is an acceptable value for this parameter.
 
136
     * @param duration The notification display duration in milliseconds. So if you want 2 seconds, you need
 
137
     * to multiply it by 1000; 2 seconds times 1000 = 2000 milliseconds.
 
138
     */
 
139
    public Notification(JFrame window, WindowPosition windowPosition, int borderX, int borderY, int duration) {
 
140
 
 
141
        // JFrame object
 
142
        this.windowType = WindowType.JFRAME;
 
143
        this.windowJWindow = null;
 
144
 
 
145
        // setting some attributes
 
146
        this.windowPosition = windowPosition;
 
147
        this.windowJFrame = window;
 
148
        this.borderX = borderX;
 
149
        this.borderY = borderY;
 
150
 
 
151
        // window attributes
 
152
        this.thisHeight = windowJFrame.getHeight();
 
153
        this.thisWidth = windowJFrame.getWidth();
 
154
 
 
155
        // set the animation duration
 
156
        this.duration = duration;
 
157
 
 
158
        {
 
159
            // retrieve the screen resolution and set some attributes
 
160
            Rectangle rect = getScreenResolution();
 
161
            this.boundX = rect.getWidth();
 
162
            this.boundY = rect.getHeight();
 
163
        }
 
164
 
 
165
        // second calculation: based on the window position and the provided
 
166
        // values, calculate positions on screen and the global payload for
 
167
        // that specific region
 
168
        switch (this.windowPosition) {
 
169
            case BOTTOMRIGHT:
 
170
                this.positionX = this.boundX - (this.thisWidth + this.borderX);
 
171
                this.positionY = this.boundY - (this.thisHeight + this.borderY);
 
172
                break;
 
173
            case BOTTOMLEFT:
 
174
                this.positionX = this.borderX;
 
175
                this.positionY = this.boundY - (this.thisHeight + this.borderY);
 
176
                break;
 
177
            case TOPRIGHT:
 
178
                this.positionX = this.boundX - (this.thisWidth + this.borderX);
 
179
                this.positionY = this.borderY;
 
180
                break;
 
181
            case TOPLEFT:
 
182
                this.positionX = this.borderX;
 
183
                this.positionY = this.borderY;
 
184
                break;
 
185
        }
 
186
    }
 
187
 
 
188
    /**
 
189
     * Constructor method for a basic <code>javax.swing.JWindow</code> object.
 
190
     * It basically builds the notification model according to the provided
 
191
     * parameters. Just keep in mind the provided <code>javax.swing.JWindow</code>
 
192
     * is <b>disposed</b> after the notification being displayed. Check the
 
193
     * following example:
 
194
     * @code
 
195
     * JWindow window = new JWindow();
 
196
     * Notification note = new Notification(window, WindowPosition.BOTTOMRIGHT, 25, 25, 1000);
 
197
     * NotificationQueue queue = new NotificationQueue();
 
198
     * queue.add(note);
 
199
     * @endcode
 
200
     * @param window The window to act as a notification. Note that a <code>javax.swing.JWindow</code>
 
201
     * object has no borders by default, so there is no need of removing them.
 
202
     * @param windowPosition The window position on screen. You may choose one amongst
 
203
     * four states, each one representing the screen corners.
 
204
     * @param borderX The distance in pixels the window must keep from the X axis border. If
 
205
     * the notification is right-aligned, this border will be from the right side, and so forth.
 
206
     * Usually 50 pixels or less is an acceptable value for this parameter.
 
207
     * @param borderY The distance in pixels the window must keep from the Y axis border. If
 
208
     * the notification is aligned from the top, this border will be from the top itself, and so forth.
 
209
     * Usually 50 pixels or less is an acceptable value for this parameter.
 
210
     * @param duration The notification display duration in milliseconds. So if you want 2 seconds, you need
 
211
     * to multiply it by 1000; 2 seconds times 1000 = 2000 milliseconds.
 
212
     */
 
213
    public Notification(JWindow window, WindowPosition windowPosition, int borderX, int borderY, int duration) {
 
214
 
 
215
        // JFrame object
 
216
        this.windowType = WindowType.JWINDOW;
 
217
        this.windowJFrame = null;
 
218
 
 
219
        // setting some attributes
 
220
        this.windowPosition = windowPosition;
 
221
        this.windowJWindow = window;
 
222
        this.borderX = borderX;
 
223
        this.borderY = borderY;
 
224
 
 
225
        // window attributes
 
226
        this.thisHeight = windowJWindow.getHeight();
 
227
        this.thisWidth = windowJWindow.getWidth();
 
228
 
 
229
        // set the animation duration
 
230
        this.duration = duration;
 
231
 
 
232
        {
 
233
            // retrieve the screen resolution and set some attributes
 
234
            Rectangle rect = getScreenResolution();
 
235
            this.boundX = rect.getWidth();
 
236
            this.boundY = rect.getHeight();
 
237
        }
 
238
 
 
239
        // second calculation: based on the window position and the provided
 
240
        // values, calculate positions on screen and the global payload for
 
241
        // that specific region
 
242
        switch (this.windowPosition) {
 
243
            case BOTTOMRIGHT:
 
244
                this.positionX = this.boundX - (this.thisWidth + this.borderX);
 
245
                this.positionY = this.boundY - (this.thisHeight + this.borderY);
 
246
                break;
 
247
            case BOTTOMLEFT:
 
248
                this.positionX = this.borderX;
 
249
                this.positionY = this.boundY - (this.thisHeight + this.borderY);
 
250
                break;
 
251
            case TOPRIGHT:
 
252
                this.positionX = this.boundX - (this.thisWidth + this.borderX);
 
253
                this.positionY = this.borderY;
 
254
                break;
 
255
            case TOPLEFT:
 
256
                this.positionX = this.borderX;
 
257
                this.positionY = this.borderY;
 
258
                break;
 
259
        }
 
260
    }
 
261
 
 
262
    /**
 
263
     * Calculates the screen size.
 
264
     * @return A <code>java.awt.Rectangle</code> with the exact size of the screen.
 
265
     */
 
266
    private Rectangle getScreenResolution() {
 
267
        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
 
268
        return environment.getMaximumWindowBounds();
 
269
    }
 
270
 
 
271
    /**
 
272
     * Calculates the current window position based on the Y axis and the
 
273
     * fraction of elapsed time.
 
274
     * @param x Fraction of elapsed time. This value is on a continuum interval, 0 <= x <= 1.
 
275
     * @return An <code>int</code> value representing the current Y value according to the
 
276
     * elapsed time.
 
277
     */
 
278
    private int calculateCurrentPositionOnY(float x) {
 
279
 
 
280
        int result = 0;
 
281
 
 
282
        // checks if the animation is the beginning
 
283
        if (animationFrame == AnimationFrame.ONSHOW) {
 
284
 
 
285
            // calculates the position, using the following math function
 
286
            switch (windowPosition) {
 
287
                case BOTTOMRIGHT:
 
288
                case BOTTOMLEFT:
 
289
                    result = (int) (positionY + ((boundY - positionY) * (1 - x)));
 
290
                    break;
 
291
                case TOPRIGHT:
 
292
                case TOPLEFT:
 
293
                    result = (int) (positionY - ((thisHeight + borderY) * (1 - x)));
 
294
                    break;
 
295
            }
 
296
 
 
297
        } else {
 
298
 
 
299
            // animation is now closing
 
300
            if (animationFrame == AnimationFrame.ONCLOSE) {
 
301
 
 
302
                // calculates the position, now using the inverse math function
 
303
                switch (windowPosition) {
 
304
                    case BOTTOMRIGHT:
 
305
                    case BOTTOMLEFT:
 
306
                        result = (int) (positionY + ((boundY - positionY) * (x)));
 
307
                        break;
 
308
                    case TOPRIGHT:
 
309
                    case TOPLEFT:
 
310
                        result = (int) (positionY - ((thisHeight + borderY) * (x)));
 
311
                        break;
 
312
                }
 
313
 
 
314
            } else {
 
315
 
 
316
                // seems animation is now on display, then just return the very
 
317
                // same position
 
318
                result = (int) positionY;
 
319
            }
 
320
 
 
321
        }
 
322
 
 
323
        return result;
 
324
    }
 
325
 
 
326
    /**
 
327
     * Implements the <code>timingEvent</code> method from <code>org.jdesktop.animation.timing.TimingTarget</code>.
 
328
     * Please don't call this function directly.
 
329
     * @param f The continnum interval referring to the animation.
 
330
     */
 
331
    public void timingEvent(float f) {
 
332
 
 
333
        // animate the window based on the Y axis
 
334
        setCurrentWindowBounds((int) positionX, calculateCurrentPositionOnY(f), thisWidth, thisHeight);
 
335
 
 
336
    }
 
337
 
 
338
    /**
 
339
     * Implements the <code>begin</code> method from <code>org.jdesktop.animation.timing.TimingTarget</code>.
 
340
     * This method is called before animation begins. Please don't call this function directly.
 
341
     */
 
342
    public void begin() {
 
343
        // empty body
 
344
    }
 
345
 
 
346
    /**
 
347
     * Implements the <code>end</code> method from <code>org.jdesktop.animation.timing.TimingTarget</code>.
 
348
     * This method is called after the animation finishes. Please don't call this function directly.
 
349
     */
 
350
    public void end() {
 
351
 
 
352
        // checks if animation just finished the presenting state
 
353
        if (animationFrame == AnimationFrame.ONSHOW) {
 
354
 
 
355
            // create a new animation handler
 
356
            animatorHandlerOnDisplay = new Animator(duration, 1, Animator.RepeatBehavior.LOOP, this);
 
357
 
 
358
            // sets the current animation state
 
359
            animationFrame = AnimationFrame.ONDISPLAY;
 
360
 
 
361
            // run it
 
362
            animatorHandlerOnDisplay.start();
 
363
        } else {
 
364
 
 
365
            // now checking if animation just finished displaying
 
366
            if (animationFrame == AnimationFrame.ONDISPLAY) {
 
367
 
 
368
                // create a new animation handler
 
369
                animatorHandlerOnClose = new Animator(timeToAnimate, 1, Animator.RepeatBehavior.LOOP, this);
 
370
 
 
371
                // sets the current animation state
 
372
                animationFrame = AnimationFrame.ONCLOSE;
 
373
 
 
374
                // run it
 
375
                animatorHandlerOnClose.start();
 
376
            } else {
 
377
 
 
378
                // animation is done, so hide and dispose window
 
379
                setCurrentWindowVisible(false);
 
380
                disposeCurrentWindow();
 
381
 
 
382
 
 
383
            }
 
384
        }
 
385
 
 
386
    }
 
387
 
 
388
    /**
 
389
     * Implements the <code>repeat</code> method from <code>org.jdesktop.animation.timing.TimingTarget</code>.
 
390
     * This function is called on every animation repetition. Please don't call this function directly.
 
391
     */
 
392
    public void repeat() {
 
393
        // empty body
 
394
    }
 
395
 
 
396
    /**
 
397
     * Performs the animation itself based on the parameters provided in the
 
398
     * constructor method. Keep in mind this method is synchronized. Check
 
399
     * the following example:
 
400
     * @code
 
401
     * JWindow window = new JWindow();
 
402
     * Notification note = new Notification(window, WindowPosition.BOTTOMRIGHT, 25, 25, 1000);
 
403
     * note.animate();
 
404
     * @endcode
 
405
     * Wherever possible, please use the new notification queue manager
 
406
     * <b>net.sf.jcarrierpigeon.NotificationQueue</b>.
 
407
     */
 
408
    public synchronized void animate() {
 
409
 
 
410
        // set the animation state
 
411
        animationFrame = AnimationFrame.ONSHOW;
 
412
 
 
413
        // define some window properties
 
414
        setCurrentWindowAlwaysOnTop(true);
 
415
        setCurrentWindowVisible(true);
 
416
 
 
417
        // defines the animator handler from Timing Framework
 
418
        // first animator handler
 
419
        animatorHandlerOnShow = new Animator(timeToAnimate, 1, Animator.RepeatBehavior.LOOP, this);
 
420
 
 
421
        // start animation
 
422
        animatorHandlerOnShow.start();
 
423
    }
 
424
 
 
425
    /**
 
426
     * Checks if the notification process is still running. It basically calls the
 
427
     * <code>isRunning</code> method from <code>org.jdesktop.animation.timing.Animator</code>.
 
428
     * @return <code>true</code> if the notification is still running, or <code>false</code>
 
429
     * otherwise.
 
430
     */
 
431
    public boolean isRunning() {
 
432
        if ((animatorHandlerOnShow.isRunning())
 
433
                || (animatorHandlerOnDisplay.isRunning())
 
434
                || (animatorHandlerOnClose).isRunning()) {
 
435
            return true;
 
436
        } else {
 
437
            return false;
 
438
        }
 
439
    }
 
440
 
 
441
    /**
 
442
     * Sets the bounds of the current window. It's basically a call to the
 
443
     * inner window <code>setBounds</code> method.
 
444
     * @param x Coordinate X
 
445
     * @param y Coordinate Y
 
446
     * @param width Width
 
447
     * @param height Height
 
448
     */
 
449
    private void setCurrentWindowBounds(int x, int y, int width, int height) {
 
450
        switch (windowType) {
 
451
            case JFRAME:
 
452
                windowJFrame.setBounds(x, y, width, height);
 
453
                break;
 
454
            case JWINDOW:
 
455
                windowJWindow.setBounds(x, y, width, height);
 
456
                break;
 
457
        }
 
458
    }
 
459
 
 
460
    /**
 
461
     * Sets the visibility of the current window. It's basically a call to the
 
462
     * inner window <code>setVisible</code> method.
 
463
     * @param value <code>true</code> if window should be visible, or <code>false</code>
 
464
     * otherwise.
 
465
     */
 
466
    private void setCurrentWindowVisible(boolean value) {
 
467
        switch (windowType) {
 
468
            case JFRAME:
 
469
                windowJFrame.setVisible(value);
 
470
                break;
 
471
            case JWINDOW:
 
472
                windowJWindow.setVisible(value);
 
473
                break;
 
474
        }
 
475
    }
 
476
 
 
477
    /**
 
478
     * Sets the window parameter of being on top of other windows. It's basically
 
479
     * a call to the inner window <code>setAlwaysOnTop</code> method.
 
480
     * @param value <code>true</code> if window should be on top of other windows, or
 
481
     * <code>false</code> otherwise.
 
482
     */
 
483
    private void setCurrentWindowAlwaysOnTop(boolean value) {
 
484
        switch (windowType) {
 
485
            case JFRAME:
 
486
                windowJFrame.setAlwaysOnTop(value);
 
487
                break;
 
488
            case JWINDOW:
 
489
                windowJWindow.setAlwaysOnTop(value);
 
490
                break;
 
491
        }
 
492
    }
 
493
 
 
494
    /**
 
495
     * Dispose the current window. It's basically a call to the inner window
 
496
     * <code>dispose</code> method.
 
497
     */
 
498
    private void disposeCurrentWindow() {
 
499
        switch (windowType) {
 
500
            case JFRAME:
 
501
                windowJFrame.dispose();
 
502
                break;
 
503
            case JWINDOW:
 
504
                windowJWindow.dispose();
 
505
                break;
 
506
        }
 
507
    }
 
508
 
 
509
    /**
 
510
     * Sets the animation speed. This method was rewritten and the name was
 
511
     * replaced by a more meaningful one. Check the following example:
 
512
     * @code
 
513
     * JWindow window = new JWindow();
 
514
     * Notification note = new Notification(window, WindowPosition.BOTTOMRIGHT, 25, 25, 1000);
 
515
     * note.setAnimationSpeed(500);
 
516
     * NotificationQueue queue = new NotificationQueue();
 
517
     * queue.add(note);
 
518
     * @endcode
 
519
     * @param milliseconds The notification effects duration in milliseconds.
 
520
     * Usually 500 milliseconds or less is an acceptable value for this parameter.
 
521
     */
 
522
    public void setAnimationSpeed(int milliseconds) {
 
523
        this.timeToAnimate = milliseconds;
 
524
    }
 
525
}