/* * AnimatedImageButton.java * * Copyright (C) 1996 Shaun Terry. All Rights Reserved. */ package spt.gui; import java.awt.Graphics; import java.awt.Image; import java.awt.Event; import java.util.Vector; import spt.gui.ImageButton; import spt.gui.ImagePanel; /** * A push button on which animations can be displayed. A text label * may also be displayed. * * @author Shaun Terry */ public class AnimatedImageButton extends ImageButton implements Runnable { private Thread me; private Vector images = new Vector(); private Vector delays = new Vector(); private int currImage = 0; private boolean repeat = true; private boolean readyToAnimate = false; private boolean animateOnEnter = false; /** Create a button. The animation sequence must be supplied * later. */ public AnimatedImageButton() { this(null); } /** Create a button with a text label. The animation sequence * must be supplied later. */ public AnimatedImageButton(String label) { super(null, label); start(); } /** Starts the animation. Generally used only after a call to stop(). * @see #startAnimation */ public void start() { if (!readyToAnimate) return; me = new Thread(this); // If animating on mouse enter only, set MAX_PRIO for best performance if (animateOnEnter) me.setPriority(Thread.MAX_PRIORITY); me.start(); } /** Stops the animation. */ public void stop() { if (me != null) me.stop(); me = null; } /** The entry point of the animation thread. */ public void run() { while (true) { setImage((Image) images.elementAt(currImage)); if (currImage == images.size()-1 && !repeat) { currImage = 0; // In case they want to resart later stop(); return; } else { try { int s = ((Integer) delays.elementAt(currImage)).intValue(); Thread.sleep(s); } catch (InterruptedException e) {} finally { if (++currImage == images.size()) currImage = 0; } } } } // Should also do a sound loop here!!!! /** Sets whether the animation whould be started when the * pointer enters the button area. */ public void setAnimateOnEnter(boolean b) { animateOnEnter = b; } /** Call this method to begin the animation after all the images * in the animation have been supplied. * @see #addImage */ // This is needed because all the images may not have been loaded // by the time the thread starts public void startAnimation() { readyToAnimate = true; setImage((Image) images.elementAt(0)); resize(); if (!animateOnEnter) start(); } /** Reset the animation back to the first frame. */ public void resetAnimation() { currImage = 0; setImage((Image) images.elementAt(currImage)); repaint(); } /** Should the animation repeat or just run once? */ public void setRepeat(boolean b) { repeat = b; } /** Add the next image to the animation with a default delay * after the frame. */ public void addImage(Image i) { addImage(i, 300); // default is 200 ms } /** Add the next image to the animation. During playback * the given number of milliseconds should be paused before the * next frame. */ public void addImage(Image i, int delay) { images.addElement(i); delays.addElement(new Integer(delay)); } /** Disable the button. The animation is stopped and a "disabled" * version of the current image is displayed. */ public void disable() { stop(); super.disable(); } public boolean mouseEnter(Event e, int x, int y) { if (animateOnEnter) { if (!readyToAnimate) startAnimation(); start(); } super.mouseEnter(e, x, y); return true; } public boolean mouseExit(Event e, int x, int y) { if (animateOnEnter) { stop(); resetAnimation(); } super.mouseExit(e, x, y); return true; } }