Package ch.swingfx.timer

Source Code of ch.swingfx.timer.AnimationTimer$AnimationTarget

/*
* This library is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation. For the terms of this
* license, see licenses/gpl_v3.txt or <http://www.gnu.org/licenses/>.
*
* You are free to use this library under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* Alternatively, you can license this library under a commercial
* license, as set out in licenses/commercial.txt.
*/

package ch.swingfx.timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.SwingUtilities;
import javax.swing.Timer;

/**
* Class for simple animation. Example:<br />
* <pre>
* AnimationTimer at = new AnimationTimer(FrameRate.FPS_25);
* at.setDuration(2500); // 2500 milliseconds
* at.setAnimationTarget(new AnimationTarget() {
*     public void event(AnimationTimer timer, float fraction) {
*      // between begin and end.
*      // fraction represents the time passed (0f = 0%, 1f = 100%)
*    }
*    public void begin(AnimationTimer timer) {
*      // start of the animation     
*    }
*    public void end(AnimationTimer timer) {
*      // end of the animation
*    }
* });
* at.start();
* </pre>
* @author Heinrich Spreiter
*/
public class AnimationTimer {
  /**
   * Frame rates for the {@link AnimationTimer}<br />
   * Note: These frame rates are approximations.
   * @author Heinrich Spreiter
   */
  public enum FrameRate {
    FPS_15(66),
    FPS_20(50),
    FPS_25(40),
    FPS_30(33),
    FPS_40(25),
    FPS_50(20)
    ;
   
    /** The delay for the timer */
    private final int fDelay;
    FrameRate(int delay) {
      fDelay = delay;
    }
   
    public int delay() {
      return fDelay;
    }
  }
 
  /** The timer for the animation */
  private final Timer fTimer;
  /** Animation events get sent to this target */
  private AnimationTarget fAnimationTarget;
  /** Stores the start time of the animation so we can calculate the fraction */
  private long fAnimationStartTime;
  /** Duration of the animation in milliseconds */
  private long fDuration;

  /**
   * Creates an {@link AnimationTimer} with a default frame rate of 25
   */
  public AnimationTimer() {
    this(FrameRate.FPS_25);
  }
 
  /**
   * Creates an {@link AnimationTimer} with an specified frame rate
   * @param fps {@link FrameRate} we want to use for this {@link AnimationTimer}
   */
  public AnimationTimer(FrameRate fps) {
        fTimer = new Timer(fps.delay(), new TimerActionListener());
  }
 
  /**
   * Set the duration of the animation
   * @param duration the duration of the animation
   */
  public void setDuration(long duration) {
    fDuration = duration;
  }
 
  /**
   * Start the animation
   */
  public void start() {
    if(!fTimer.isRunning()) {
      if(fAnimationTarget == null) {
        throw new IllegalStateException("Animation target is not set!");
      }
      fAnimationStartTime = System.nanoTime() / 1000000;
      final Runnable r = new Runnable() {
        public void run() {
          fAnimationTarget.begin(AnimationTimer.this);
        }
      };
      if(SwingUtilities.isEventDispatchThread()) {
        r.run();
      } else {
        SwingUtilities.invokeLater(r);
      }
      fTimer.start();
    }
  }
 
  /**
   * End the animation before duration has passed
   */
  public void stop() {
    if(fTimer.isRunning()) {
      fTimer.stop();
      final Runnable r = new Runnable() {
        public void run() {
          fAnimationTarget.end(AnimationTimer.this);
        }
      };
      if(SwingUtilities.isEventDispatchThread()) {
        r.run();
      } else {
        SwingUtilities.invokeLater(r);
      }
    }
  }
 
  /**
   * Set the animation target
   * @param target the animation target
   */
  public void setAnimationTarget(AnimationTarget target) {
    this.fAnimationTarget = target;
  }
 
  /**
   * Handles the calculation of the time that has elapsed since the start
   * and sends it to the {@link AnimationTarget}
   * @author Heinrich Spreiter
   *
   */
  private class TimerActionListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      final long currentAnimationTime = System.nanoTime() / 1000000;
      final long totalTime = currentAnimationTime - fAnimationStartTime;
      if(totalTime > fDuration) {
        fAnimationStartTime = totalTime;
      }
      float fraction = (float) totalTime / fDuration;
      fraction = Math.min(1f, fraction);
      if(fraction == 1f) {
        stop();
      } else {
        fAnimationTarget.event(AnimationTimer.this, fraction);
      }
    }
  }
 
  /**
   * Used with {@link AnimationTimer}.setAnimationTarget().<br />
   * Implement this interface to receive events from the {@link AnimationTimer}
   * @author Heinrich Spreiter
   *
   */
  public interface AnimationTarget {
    /**
     * Fired only once when the animation starts
     * @param timer the timer that fired the event
     */
    public void begin(AnimationTimer timer);
    /**
     * Fired when the animation is running
     * @param timer the timer that fired the event
     * @param fraction value between 0f and 1f that represents the time that has ellapsed
     */
    public void event(AnimationTimer timer, float fraction);
    /**
     * Fired only once when the animation stopped
     * @param timer the timer that fired the event
     */
    public void end(AnimationTimer timer);
  }
}
TOP

Related Classes of ch.swingfx.timer.AnimationTimer$AnimationTarget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.