001: /*
002: * Copyright (c) 2001-2006 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.animation;
032:
033: import java.util.Iterator;
034: import java.util.LinkedList;
035: import java.util.List;
036:
037: /**
038: * An abstract class that minimizes the effort required to implement
039: * the {@link Animation} interface. Defines the duration and freezed state
040: * and provides a listener list.
041: *
042: * @author Karsten Lentzsch
043: * @version $Revision: 1.1 $
044: */
045: public abstract class AbstractAnimation implements Animation {
046:
047: private final long duration;
048: private final boolean freezed;
049: private final List listenerList = new LinkedList();
050:
051: private boolean active = false;
052:
053: // Instance Creation *****************************************************
054:
055: /**
056: * Constructs an <code>Animation</code> with the specified duration.
057: *
058: * @param duration the animation's duration
059: */
060: protected AbstractAnimation(long duration) {
061: this (duration, false);
062: }
063:
064: /**
065: * Constructs an <code>Animation</code> with the specified duration
066: * and freezed mode.
067: *
068: * @param duration the animation's duration
069: * @param freezed true indicates that the effect will be retained after
070: * the animation is finished, false resets the effect to the time 0
071: */
072: protected AbstractAnimation(long duration, boolean freezed) {
073: this .duration = duration;
074: this .freezed = freezed;
075: }
076:
077: // ***********************************************************************
078:
079: /**
080: * Returns this animation's duration.
081: *
082: * @return this animation's duration
083: */
084: public final long duration() {
085: return duration;
086: }
087:
088: /**
089: * Answers whether the animation effect should be freezed after
090: * we exceeded the animation's duration. If this is not the case,
091: * the animation effect of time 0 will be set.
092: *
093: * @return true indicates that the effect will be retained if the
094: * animation duration exceeded; false indicates that the effect
095: * will be reset
096: */
097: public final boolean isFreezed() {
098: return freezed;
099: }
100:
101: /**
102: * Applies the animation effect for the given time to the animation target.
103: *
104: * @param time the time used to determine the animation effect
105: */
106: protected abstract void applyEffect(long time);
107:
108: /**
109: * Performs the animation at the given time: applies the animation
110: * effect to the animation target, fires appropriate events,
111: * and resets the effect if we exceeded the animations duration.
112: *
113: * @param time the time used to determine the animation effect
114: */
115: public void animate(long time) {
116: if (time >= duration) {
117: if (active) {
118: applyEffect(isFreezed() ? duration - 1 : 0);
119: fireAnimationStopped(time);
120: active = false;
121: }
122: return;
123: }
124:
125: if (!active) {
126: active = true;
127: fireAnimationStarted(time);
128: }
129: applyEffect(time);
130: }
131:
132: /**
133: * Adds an <code>AnimationListener</code> to this animation.
134: *
135: * @param listener the <code>AnimationListener</code> to add
136: */
137: public final void addAnimationListener(AnimationListener listener) {
138: listenerList.add(listener);
139: }
140:
141: /**
142: * Removes an <code>AnimationListener</code> to this animation.
143: *
144: * @param listener the <code>AnimationListener</code> to remove
145: */
146: public final void removeAnimationListener(AnimationListener listener) {
147: listenerList.remove(listener);
148: }
149:
150: /**
151: * Fires an event that indicates that the animation has been started
152: * at the specified time.
153: *
154: * @param time the time that will be reported in the event
155: */
156: protected final void fireAnimationStarted(long time) {
157: AnimationEvent e = new AnimationEvent(this ,
158: AnimationEvent.STARTED, time);
159: for (Iterator i = listenerList.iterator(); i.hasNext();) {
160: AnimationListener listener = (AnimationListener) i.next();
161: listener.animationStarted(e);
162: }
163: }
164:
165: /**
166: * Fires an event that indicates that the animation has been stopped
167: * at the specified time.
168: *
169: * @param time the time that will be reported in the event
170: */
171: protected final void fireAnimationStopped(long time) {
172: AnimationEvent e = new AnimationEvent(this ,
173: AnimationEvent.STOPPED, time);
174: for (Iterator i = listenerList.iterator(); i.hasNext();) {
175: AnimationListener listener = (AnimationListener) i.next();
176: listener.animationStopped(e);
177: }
178: }
179:
180: /**
181: * Returns a string representation for this animation.
182: *
183: * @return a string representation for this animation
184: */
185: public String toString() {
186: return "[" + getClass().getName() + "; duration=" + duration
187: + "; active=" + active + ']';
188: }
189: }
|