/* Rotator An applet that animates a sequence of frames stored in a single file. Based on JavaSpin by Blake Stone (http://www.dkw.com/bstone). http://rsb.info.nih.gov/nih-image/Java/Rotator/ */ /* * Modified by abb@nuccard.eushc.org, http://www.emory.edu/CRL/ * on 6/6/96 to include: * 1. zooming to fit window. * 2. autoReverse. * * @version 1.1 96/06/13 * @author Andrew Barclay * * Required Params: * src -- Name of source image file * width -- Width of display window * height -- Height of display window * Optional Params: * frames -- Number of source image frames (default: 1) * frameWidth -- Width of source image frames (default: width) * frameHeight -- Height of source image frames (default: height) * rate -- Rate in frames per second (default: 6) * columns -- Number of frames across the image (default: frames) * rows -- Number of frames down the image (default: 1) * autoReverse -- self explanatory? (default: false) */ // I like to know what I'm importing for sanity checks. import java.applet.Applet ; import java.awt.Color ; import java.awt.Event ; import java.awt.Graphics ; import java.awt.Image ; public class Rotator extends Applet implements Runnable { int windowWidth, windowHeight; int frameWidth, frameHeight; int nColumns = 1; int nRows = 1; int nFrames = 1; int delay = 167; // milliseconds (6 frames/sec) int frame = -1 ; int frameIncr = 1 ; boolean autoReverse = false ; boolean suspended = false; Thread spinThread ; Image spinImage; public String getAppletInfo() { return "Rotator based on JavaSpin by Blake Stone" ; } public String[][] getParameterInfo() { String[][] info = { {"src", "string", "path of source image file"}, {"width", "int", "width of display window"}, {"height", "int", "height of display window"}, {"frames", "int", "number of source frames [1]"}, {"frameWidth", "int", "width of source frame [width]"}, {"frameHeight", "int", "height of source frame [height]"}, {"rate", "int", "frames/second [6]"}, {"columns", "int", "frames across source image [1]"}, {"rows", "int", "frames down source image [1]"}, {"autoReverse", "boolean", "self explanatory? [false]"}, } ; return info ; } /* ============================================================ * Initializing stuff: */ public void init() { String param ; // Required params: param = getParameter("src"); // for backward compatibility with Rotator: if (param == null) param = getParameter("image") ; spinImage = getImage( getCodeBase(), param ) ; windowWidth = Integer.parseInt( getParameter( "width" ) ) ; windowHeight = Integer.parseInt( getParameter( "height" ) ) ; // Optional params: param = getParameter("frames"); if (param != null) nFrames = Integer.parseInt(param); param = getParameter("frameWidth"); if (param != null) frameWidth = Integer.parseInt(param); else frameWidth = windowWidth ; param = getParameter("frameHeight"); if (param != null) frameHeight = Integer.parseInt(param); else frameHeight = windowHeight ; param = getParameter("rate"); if (param != null) delay =1000 / Integer.parseInt(param); param = getParameter("columns"); if (param != null) nColumns = Integer.parseInt(param); param = getParameter("rows"); if (param != null) nRows = Integer.parseInt(param); param = getParameter("autoreverse"); if( param != null ) autoReverse = (Boolean.valueOf( param )).booleanValue() ; if (delay < 5) delay = 5; if (nFrames == 1) nFrames = nColumns * nRows; if (nColumns == 1 && nRows == 1) nColumns = nFrames; } /* ============================================================ * Spinning thread stuff. */ public void start() { if (spinThread == null && nFrames > 1) { spinThread = new Thread (this, "Spin"); spinThread.start(); } } public void stop() { if( spinThread != null ) { spinThread.stop(); spinThread = null; } } public void run() { while (spinThread != null) { repaint() ; try { spinThread.sleep(delay); } catch (InterruptedException e) { } } } /* ============================================================ * Image painting stuff. */ public void update( Graphics gr ) { paint( gr ) ; } public void incrFrame() { privateSetFrame( frame+frameIncr ) ; repaint() ; } public void incrFrame( int incr ) { privateSetFrame( frame+incr ) ; repaint() ; } public void setFrame( int frame ) { privateSetFrame( frame ) ; repaint() ; } private synchronized void privateSetFrame( int frame ) { if( autoReverse ) { if( frame >= nFrames ) { int absincr = Math.abs( frameIncr ) ; frame = nFrames-absincr ; frameIncr = -absincr ; } else if( frame < 0 ) { int absincr = Math.abs( frameIncr ) ; frame = absincr ; frameIncr = absincr ; } } else { if( frame >= nFrames ) { frame -= nFrames ; } else if( frame < 0 ) { frame += nFrames ; } } this.frame = frame ; } public void paint( Graphics gr ) { /* * Update frame number before displaying image, so that * the frame number will reflect the currently displayed * image. */ if( !suspended ) { privateSetFrame( frame+frameIncr ) ; } /* * Draw current frame using negative coordinates * for x, y so drawImage will crop frame. */ gr.drawImage ( spinImage, -windowWidth * (frame % nColumns), -windowHeight * ((frame / nColumns) % nRows), (nColumns*windowWidth), (nRows*windowHeight), this ) ; if( suspended ) { int y = (gr.getFontMetrics()).getHeight() ; gr.setColor( Color.red ) ; gr.drawString( Integer.toString(frame+1), 1, y ) ; } } public void toggleSpin() { if (suspended) spinThread.resume(); else spinThread.suspend(); suspended = !suspended; repaint() ; } public boolean mouseDown(Event evt, int x, int y) { toggleSpin() ; return true; } public boolean keyDown( Event evt, int key ) { switch( key ) { case Event.RIGHT: case 'l': case ' ': incrFrame( 1 ) ; return true ; case Event.LEFT: case 'h': // BackSpace? case 8: incrFrame( -1 ) ; return true ; case Event.UP: case '+': if( delay > 105 ) { delay -= 100 ; } return true ; case Event.DOWN: case '-': delay += 100 ; return true ; default: showStatus( "key press="+key ) ; toggleSpin() ; return true ; } } }// Rotator