![JAR search and dependency download from the Maven repository](/logo.png)
org.jdesktop.animation.timing.triggers.Trigger Maven / Gradle / Ivy
Show all versions of timingframework Show documentation
/**
* Copyright (c) 2006, 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.
*/
package org.jdesktop.animation.timing.triggers;
import org.jdesktop.animation.timing.Animator;
/**
* This abstract class should be overridden by any class wanting to
* implement a new Trigger. The subclass will define the events to trigger
* off of and any listeners to handle those events. That subclass will call
* either {@link #fire()} or {@link #fire(TriggerEvent)} to start the
* animator based on an event that occurred.
*
* Subclasses should call one of the constructors in Trigger, according to
* whether they want Trigger to discern between different TriggerEvents
* and whether they want Trigger to auto-reverse the animation based on
* opposite TriggerEvents.
*
* Subclasses should call one of the fire
methods based on
* whether they want Trigger to perform any event logic or simply start
* the animation.
*
* @author Chet
*/
public abstract class Trigger {
private boolean disarmed = false;
private Animator animator, reverseAnimator;
private TriggerEvent triggerEvent;
private boolean autoReverse = false;
/**
* Creates a Trigger that will start the animator when {@link #fire()}
* is called. Subclasses call this method to set up a simple Trigger
* that will be started by calling {@link #fire()}, and will have
* no dependency upon the specific {@link TriggerEvent} that must have
* occurred to start the animator.
* @param animator the Animator that will start when the Trigger
* is fired
*/
protected Trigger(Animator animator) {
this(animator, null);
}
/**
* Creates a Trigger that will start the animator when
* {@link #fire(TriggerEvent)} is called with an event that equals
* triggerEvent.
* @param animator the Animator that will start when the Trigger
* is fired
* @param triggerEvent the TriggerEvent that must occur for this
* Trigger to fire
*/
protected Trigger(Animator animator, TriggerEvent triggerEvent) {
this(animator, triggerEvent, false);
}
/**
* Creates a Trigger that will start the animator when
* {@link #fire(TriggerEvent)} is called with an event that equals
* triggerEvent. Also, automatically stops and reverses animator when
* opposite event occurs, and stops reversing animator likewise
* when triggerEvent occurs.
* @param animator the Animator that will start when the Trigger
* is fired
* @param triggerEvent the TriggerEvent that must occur for this
* Trigger to fire
* @param autoReverse flag to determine whether the animator should
* stop and reverse based on opposite triggerEvents.
* @see TriggerEvent#getOppositeEvent()
*/
protected Trigger(Animator animator, TriggerEvent triggerEvent,
boolean autoReverse) {
this.animator = animator;
this.triggerEvent = triggerEvent;
this.autoReverse = autoReverse;
}
/**
* This method disables this Trigger and effectively noop's any actions
* that would otherwise occur
*/
public void disarm() {
disarmed = true;
}
/**
* Called by subclasses to start the animator if currentEvent equals
* the event that the Trigger is based upon. Also, if the Trigger is
* set to autoReverse, stops and reverses the animator running in the
* opposite direction as appropriate.
* @param currentEvent the {@link TriggerEvent} that just occurred, which
* will be compared with the TriggerEvent used to construct this Trigger
* and determine whether the animator should be started or reversed
*/
protected void fire(TriggerEvent currentEvent) {
if (disarmed) {
return;
}
if (currentEvent == triggerEvent) {
// event occurred; fire the animation
if (autoReverse) {
if (animator.isRunning()) {
float f = animator.getTimingFraction();
animator.stop();
animator.setStartFraction(f);
} else {
animator.setStartFraction(0f);
}
}
if (animator.isRunning()) {
animator.stop();
}
animator.setStartDirection(Animator.Direction.FORWARD);
fire();
} else if (triggerEvent != null &&
currentEvent == triggerEvent.getOppositeEvent()) {
// Opposite event occurred - run reverse anim if autoReverse
if (autoReverse) {
if (animator.isRunning()) {
float f = animator.getTimingFraction();
animator.stop();
animator.setStartFraction(f);
} else {
animator.setStartFraction(1f -
animator.getStartFraction());
}
animator.setStartDirection(Animator.Direction.BACKWARD);
fire();
}
}
}
/**
* Utility method called by subclasses to start the animator. This variant
* assumes that there need be no check of the TriggerEvent that fired,
* which is useful for subclasses with simple events.
*/
protected void fire() {
if (disarmed) {
return;
}
if (animator.isRunning()) {
animator.stop();
}
animator.start();
}
}