vmm.core
Class TimerAnimation

java.lang.Object
  extended by vmm.core.TimerAnimation
All Implemented Interfaces:
Animation
Direct Known Subclasses:
BasicAnimator

public abstract class TimerAnimation
extends java.lang.Object
implements Animation

An animation that is driven by a Swing Timer. A concrete subclass of this class must implement the drawFrame() method, which is called each time the Timer fires. A subclass that has some set-up to do at the beginning of the animation should override the animationStarting() method; if the subclass has some clean-up that needs to be done when the animation ends, it should override animationEnding(). Note that the animation does not start until its start() method is invoked. Once it has been started, it will run until it ends on its own or until its cancel() method is called, either by an external agent or in the drawFrame method. While it is running, a TimerAnimation can be paused and resumed by calling the setPaused(boolean) method.

Each frame in a TimerAnimation has a frame number. It can have either a specified finite number of frames, or the frame number can be allowed to increase indiefinitely. An animation with a finite number of frames can run in any of three "looping modes": TimerAnimation.ONCE, meaning that it runs through the frames from first to last then stops; TimerAnimation.LOOP, which means that it runs from first to last frame over and over indefinitely; and TimerAnimation.OSCILLATE, which means that it runs from first frame to last then from last frame back to first in revese order, and the repeats this sequence indefinitely.

A Timere animation is capable of using a "filmstrip" to store the frames of the animation. See setUseFilmstrip(boolean). If a filmstrip is used, each frame of the animation is saved as a bitmap the first time it is computed. Then, when it is necessary to show the same frame again, the precomputed bitmap is just copied to the screen.


Field Summary
protected  Display display
           
protected  int frameNumber
          The current frame number.
static int LOOP
          Indicates a looping mode in which the frames are generated from first frame to last frame, and then sequence repeats indefinitely.
static int ONCE
          Indicates a looping mode in which the frames are generated from first frame to last frame, and then the animation ends.
static int OSCILLATE
          Indicates a looping mode in which the frames are generated from first frame to last frame, then in reverse order from last to first, and then then the same sequence is repeated indefinitely.
protected  double timeDilation
          The time dilation fact that is multiplied by all time specifications.
 
Constructor Summary
TimerAnimation()
          Construct a TimerAnimation in which the frame number will increase indefinitely forever.
TimerAnimation(int frames, int millisecondsPerFrame)
          Construct a TimerAnimation with a specified number of frames and nominal time per frame.
TimerAnimation(int frames, int millisecondsPerFrame, boolean createFilmstrip)
          Construct a TimerAnimation with a specified number of frames and time per frame, with the possibility of creating a filmstrip of the animation.
 
Method Summary
 void addChangeListener(javax.swing.event.ChangeListener listener)
          Add a ChangeListener to this animation.
protected  void animationEnding()
          Called when the animation ends, either on its own or becauce it has been canceled from somewhere else, to give a subclass a chance to do any necessary clean-up.
protected  void animationStarting()
          Called when the animation is started to give a subclass a chance to do any necessary set-up.
 void cancel()
          Cancels a running animation.
protected abstract  void drawFrame()
          This is called to draw each frame.
protected  void fireAnimationChangeEvent()
          Sends a ChangeEvent to any registered ChangeListeners.
 Filmstrip getFilmstrip()
          Returns the filmstrip that is being used to store the frames of this animation.
 java.awt.image.BufferedImage getFilmstripFrameImage()
          If this animation is creating a filmstrip and if the current frame has already been created, then the image of that frame is returned.
 boolean getFireFrameEvents()
          Tells whether frame events are fired by this animation.
 int getFrameNumber()
          Gets the current frame number.
 int getFrames()
          Returns the maximum frame number for this animation.
 int getInitialDelay()
          Gets the initial delay for this animation.
 int getLooping()
          Returns the current looping mode of the animation.
 int getMillisecondsPerFrame()
          Returns the nominal number of milliseconds per frame.
 java.lang.String getStatusText(boolean running)
          Returns null to indicate that the default text ("Animation Running" or "Animation Paused" in the English version) should be shown in the display's status bar.
 double getTimeDilation()
          Returns the current time dilation factor.
 boolean getUseFilmstrip()
          Returns true if this animation is creating a filmstrip.
 boolean isPaused()
          Tests whether the animation is currently paused.
 boolean isRunning()
          Returns true if the animation is currently running.
protected  void nextFrame(java.awt.event.ActionEvent evt)
          Respond to an event from the timer that drives the animation.
 void removeChangeListener(javax.swing.event.ChangeListener listener)
          Remove a ChangeListener from the animation, if it is currently registered as a listener.
 void setFireFrameEvents(boolean fireFrameEvents)
          If set to true, then change events are generated each time the frame changes.
 void setFrames(int frames)
          Sets the maximum frame number for this animation.
 void setInitialDelay(int initialDelayInMilliseconds)
          Sets the nominal initial delay for this animation to a specified number of milliseconds.
 void setLooping(int loopingMode)
          Sets the looping mode of the animation.
 void setMillisecondsPerFrame(int millisecondsPerFrame)
          Sets the nominal number of milliseconds per frame.
 void setPaused(boolean paused)
          Pauses or unpauses a running animation.
 void setTimeDilation(double dilationFactor)
          Sets a time dilation factor that is multiplied by all time periods related to the animation.
 void setUseFilmstrip(boolean useFilmstrip)
          Set whether or not this animation uses a filmstrip.
 void start()
          Starts the animation running.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ONCE

public static final int ONCE
Indicates a looping mode in which the frames are generated from first frame to last frame, and then the animation ends. For use as a parameter to setLooping(int)

See Also:
Constant Field Values

LOOP

public static final int LOOP
Indicates a looping mode in which the frames are generated from first frame to last frame, and then sequence repeats indefinitely. For use as a parameter to setLooping(int)

See Also:
Constant Field Values

OSCILLATE

public static final int OSCILLATE
Indicates a looping mode in which the frames are generated from first frame to last frame, then in reverse order from last to first, and then then the same sequence is repeated indefinitely. For use as a parameter to setLooping(int)

See Also:
Constant Field Values

display

protected Display display

timeDilation

protected double timeDilation
The time dilation fact that is multiplied by all time specifications.


frameNumber

protected int frameNumber
The current frame number.

Constructor Detail

TimerAnimation

public TimerAnimation()
Construct a TimerAnimation in which the frame number will increase indefinitely forever. The time per frame is 50 milliseconds. The initial delay will be zero, unless it is set by setInitialDelay(int). No filmstrip is created.


TimerAnimation

public TimerAnimation(int frames,
                      int millisecondsPerFrame)
Construct a TimerAnimation with a specified number of frames and nominal time per frame. There is no initial delay, and the nominal inter-frame delay time is 50 milliseconds. The initial delay will be zero, unless it is set by setInitialDelay(int) No filmstrip is created.

Parameters:
frames - The number of frames in the animation. Any value less than or equal to zero means that the number of frames will increase indefinitely.
millisecondsPerFrame - The nominal number of milliseconds for each frame. This is used (after adjustment by the time dilation factor) as the delay time for the Swing Timer that drives the animation.

TimerAnimation

public TimerAnimation(int frames,
                      int millisecondsPerFrame,
                      boolean createFilmstrip)
Construct a TimerAnimation with a specified number of frames and time per frame, with the possibility of creating a filmstrip of the animation. The initial delay will be zero, unless it is set by setInitialDelay(int) (The actual delay times can be affected by the setTimeDilation(double) method, and the processing time used by the animation means that the actual delay cannot be made arbitrarily small.)

Calling this method with the createFilmstrip parameter set to true is the only way to create a filmstrip animation. Note that creating a filmstrip requires the cooperaiton of the Display where the animation is being shown. In fact, it is the display that actually creates the image of each frame and stores it in the TimerAnimation object.

Parameters:
frames - The number of frames in the animation. Any value less than or equal to zero means that the number of frames will increase indefinitely.
millisecondsPerFrame - The nominal number of milliseconds for each frame. This is used (after adjustment by the time dilation factor) as the delay time for the Swing Timer that drives the animation.
createFilmstrip - If this is true, then a "filmstrip" will be created as the animation is created. Once a frame has been created, the frame image is saved so that it does not have to be recreated when the frame is shown again. Note that if memory is not available for all the frames of the amimation, then frames for which there is no memory will have to be reconstructed each time they are shown. Use Filmstrip.maxFrames(int, int, boolean) to get an estimate of the number of frames that can be created.
Method Detail

drawFrame

protected abstract void drawFrame()
This is called to draw each frame. "Drawing" will probably mean setting some parameters and calling repaint, rather than doing the drawing directly. The protected member variable frameNumber is the number of the current frame; you can use this number to determine what to draw in the current frame. You can call the cancel() method to terminate the animation. The animation can also be canceled at any time when an external agent calls the cancel method. Since you can't control how the animation will end, any clean-up that has to be done when the animation ends should be done in the animationStarting() method.

Note that if this animation is creating a filmstrip, this method is called only when the frame is actually being created, ant not when a saved image of a frame is being redrawn. Saving and using the frames is managed by the Display where the animation is running.


getUseFilmstrip

public boolean getUseFilmstrip()
Returns true if this animation is creating a filmstrip.


setUseFilmstrip

public void setUseFilmstrip(boolean useFilmstrip)
Set whether or not this animation uses a filmstrip. If the value of the useFilmstrip is changed from true to false, the flimstrip and any frames that it contains are discarded.


getFilmstrip

public Filmstrip getFilmstrip()
Returns the filmstrip that is being used to store the frames of this animation. If no filmstrip is being created, then the return value will be null.


getFilmstripFrameImage

public java.awt.image.BufferedImage getFilmstripFrameImage()
If this animation is creating a filmstrip and if the current frame has already been created, then the image of that frame is returned. Otherwise, null is returned.


setLooping

public void setLooping(int loopingMode)
Sets the looping mode of the animation. This determines what happens when the last frame of the animation is reached (and therefore only has an effect on an animation that has a finite number of frames.) When the animation reaches its last frame, it can either end (TimerAnimation.ONCE), return immediately to the first frame (TimerAnimation.LOOP), or go into reverse and show the frames from last back to first and then repeating this sequence (TimerAnimation.OSCILLATE).

Parameters:
loopingMode - The looping mode for the animation. This must be one of TimerAnimation.ONCE, TimerAnimation.LOOP, or TimerAnimation.OSCILLATE; other values are ignored.

getLooping

public int getLooping()
Returns the current looping mode of the animation.

See Also:
setLooping(int)

getFrames

public int getFrames()
Returns the maximum frame number for this animation. A return value of -1 indicates that the frame number will increase indefinitely.


setFrames

public void setFrames(int frames)
Sets the maximum frame number for this animation. Frames are numbered from 0 up to this number (so that number of frames is actually one more than the number specified in this method). If set to a value less than or equal to 0, the number of frames will be unlimited. Also in this case, looping mode is forced to ONCE and the direction of the animation is set to be forward if it is currently going backwards in the OSCILLATE mode.


getFireFrameEvents

public boolean getFireFrameEvents()
Tells whether frame events are fired by this animation.

See Also:
setFireFrameEvents(boolean)

setFireFrameEvents

public void setFireFrameEvents(boolean fireFrameEvents)
If set to true, then change events are generated each time the frame changes. The default value is false. In any case, change events are sent when the animation starts and when it stops.


getFrameNumber

public int getFrameNumber()
Gets the current frame number. (Note that subclasses can use the protected member variable, frameNumber, instead of calling this method.)


getInitialDelay

public int getInitialDelay()
Gets the initial delay for this animation.

See Also:
setInitialDelay(int)

setInitialDelay

public void setInitialDelay(int initialDelayInMilliseconds)
Sets the nominal initial delay for this animation to a specified number of milliseconds. This is used as the initial delay of the Swing Timer that drives the animation. The actual delay time is adjusted by the time dilation factor.

See Also:
setTimeDilation(double)

getMillisecondsPerFrame

public int getMillisecondsPerFrame()
Returns the nominal number of milliseconds per frame.

See Also:
setMillisecondsPerFrame(int)

setMillisecondsPerFrame

public void setMillisecondsPerFrame(int millisecondsPerFrame)
Sets the nominal number of milliseconds per frame. This is used as the delay time of the Swing Timer that drives the animation. The actual time is adjusted by the time dilation factor. Because of processing time used by the animation and other tasks being run by the system, the effective delay time cannot be arbitrarily short.

Parameters:
millisecondsPerFrame - the nominal number of milliseconds per frame. The value should be positive; values less than or equal to zero are ignored.
See Also:
setTimeDilation(double)

setPaused

public void setPaused(boolean paused)
Pauses or unpauses a running animation. This has no effect if the animation is not running. While an animation is paused, no new frames are generated, and the drawFrame method will not be called.

Specified by:
setPaused in interface Animation
Parameters:
paused - Tells whether or not the animation should be paused.

isPaused

public boolean isPaused()
Tests whether the animation is currently paused.

Specified by:
isPaused in interface Animation
Returns:
returns true if the animation is running but is in a paused state; returns false if it is not running or if it is running but is not paused.
See Also:
setPaused(boolean)

setTimeDilation

public void setTimeDilation(double dilationFactor)
Sets a time dilation factor that is multiplied by all time periods related to the animation. This is used for slowing down or speeding up the animation, although only a certain amount of speed-up is possible, becasue of the actual processing time used by the animation. This applies to the initial delay and to the inter-frame time.

Specified by:
setTimeDilation in interface Animation
Parameters:
dilationFactor - The factor by which initial delay and inter-frame times are to be multiplied. The value should be non-negative. Negative values are treated as zero.

getTimeDilation

public double getTimeDilation()
Returns the current time dilation factor.

Specified by:
getTimeDilation in interface Animation
See Also:
setTimeDilation(double)

start

public void start()
Starts the animation running. An animation does not start running automatically, but only when this method is called. If the animation is already runnning, this has no effect. If the animation has already run and has finished for any reason, it is restarted from the beginning.

Specified by:
start in interface Animation

nextFrame

protected void nextFrame(java.awt.event.ActionEvent evt)
Respond to an event from the timer that drives the animation. This is "protected" so it can be overridden in very rare circumstances, such as in the SurfaceImplicit class.


cancel

public void cancel()
Cancels a running animation. If this animation is not running, this has no effect.

Specified by:
cancel in interface Animation

animationStarting

protected void animationStarting()
Called when the animation is started to give a subclass a chance to do any necessary set-up. In this class, the method does nothing.


animationEnding

protected void animationEnding()
Called when the animation ends, either on its own or becauce it has been canceled from somewhere else, to give a subclass a chance to do any necessary clean-up. In this class, the method does nothing.


isRunning

public boolean isRunning()
Returns true if the animation is currently running. When the "start" event is fired, the return value is true. When the "end" event is fired, the return value is false.

Specified by:
isRunning in interface Animation

addChangeListener

public void addChangeListener(javax.swing.event.ChangeListener listener)
Add a ChangeListener to this animation. Change events are sent when the animation stops and when it stops for any reason. The ChangeListener can distinguish the two events by calling the isRunning method, which will retrun true if the animation is starting and false if the animation has ended.

Specified by:
addChangeListener in interface Animation
Parameters:
listener - a ChangeListener that is registered to receive change events from this animation.

removeChangeListener

public void removeChangeListener(javax.swing.event.ChangeListener listener)
Remove a ChangeListener from the animation, if it is currently registered as a listener.

Specified by:
removeChangeListener in interface Animation
Parameters:
listener - to be de-registered as a ChangeListener from this animation.

fireAnimationChangeEvent

protected void fireAnimationChangeEvent()
Sends a ChangeEvent to any registered ChangeListeners. This is not likely to be used in a subclass, unless the subclass wants to send additional change events besides those sent when the animation starts and stops.


getStatusText

public java.lang.String getStatusText(boolean running)
Returns null to indicate that the default text ("Animation Running" or "Animation Paused" in the English version) should be shown in the display's status bar. This can be overridden in a subclass to show a different status message.

Specified by:
getStatusText in interface Animation
Parameters:
running - tells whether the animation is currently running.
Returns:
the text to displayed, or null to use the default text "Animation Running" or "Animation Paused"