/*--------------------------------------------------------------------------- File: AnimClass.java Package: JAWAA Beta Version 0.1 Author: Will Pierson (wcp@acpub.duke.edu) Description of Contents: Contains applet routines to run animation. --------------------------------------------------------------------------*/ /* * Susan H. Rodger, Will Pierson * Computer Science Department * Duke University * December 1996 * * Copyright (c) 1996 * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the author. The name of the author may not be used to * endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ import java.applet.*; import java.awt.*; //main class that "runs" animation public class AnimClass extends Applet implements Runnable{ boolean stop = false, time_to_die = false; String animLoc, animName; Thread animThread; Image offscreen; Animation anim; AnimPanel ap; public AnimCanvas ac; Interpreter i; Dimension r; int step, delay; ThreadGroup myGroup; public AnimClass(){ } public void init(){ animLoc = getParameter("animLoc"); animName = getParameter("animName"); r = size(); offscreen = createImage(r.width, r.height); anim = new Animation(r,offscreen, this); i = new Interpreter(anim, animLoc, animName); delay = 400; //set up graphical look setLayout(new BorderLayout()); ac = new AnimCanvas(anim, r, offscreen); ap = new AnimPanel(this); add("Center", ac); add("South", ap); myGroup = Thread.currentThread().getThreadGroup(); } //runs in separate thread, mainly because of Graphic restrictions public synchronized void run(){ // System.out.println("Running..."); i.readLine(); ac.repaint(10); while(!time_to_die){ // loop until "stop" clicked if (step == 0) stop = true; // stop if steps done while (stop == true){ //don't keep stepping when applet try{ //minimized wait(); } catch (InterruptedException e) { } } if (i.readLine() == false){ // System.out.println("Animation Done..."); return; } ac.repaint(10); try{ animThread.sleep(delay); }catch(InterruptedException e){ } try{ wait(100); } catch (InterruptedException e) { } step--; } } // redraw elements of animation public void paint(Graphics g){ // System.out.println("Repainting..."); ac.repaint(); } // pause animation public void stop(){ // System.out.println("Stopping..."); stop = true; step = 0; } //start animation moving when "start" clicked public void start(){ // System.out.println("Starting Animation..."); step = -1; if (animThread == null){ time_to_die = false; stop = true; animThread = new Thread(myGroup, this); animThread.setPriority(1); animThread.start(); } } //wake up animation from paused state public synchronized void restartAnim(){ step = -1; // System.out.println("Restarting..."); stop = false; notify(); } //animate one step public synchronized void stepAnim(){ step = 1; stop = false; notify(); } //remove animation public void killAnim(){ if (animThread != null){ time_to_die = true; animThread.stop(); // animThread.destroy(); animThread = null; } anim = new Animation(r, offscreen, this); i = new Interpreter(anim, animLoc, animName); ac.setNewAnim(anim); ac.clear = true; ac.repaint(10); ap.reset(); start(); } } //provides drawing area for animation class AnimCanvas extends Canvas{ Animation anim; Dimension r; Image offscreen; public boolean clear = false; //if true clear canvas //before redrawing public AnimCanvas(Animation a, Dimension d, Image os){ offscreen = os; r = d; resize(r); anim = a; } public void setNewAnim(Animation a){ anim = a; } public void paint(Graphics g){ //all animation graphics come // System.out.println("REPAINT"); if (clear == true){ //through this procedure clear = false; g.clearRect(0,0,r.width, r.height); } anim.redraw(); g.drawImage(offscreen,0,0, this); // System.out.println("END REPAINT"); } public void update(Graphics g){ //don't allow other update to paint(g); //clear canvas } } // presents three buttons to user class AnimPanel extends Panel{ AnimClass parent; Button pause; Button stepButton; Scrollbar speedBar; static final String START = "Start"; static final String STOP = "Stop"; static final String PAUSE = " Pause "; static final String RESTART = "Unpause"; static final String STEP = "Step"; public AnimPanel(AnimClass p){ parent = p; speedBar = new Scrollbar(Scrollbar.HORIZONTAL, 400, 20, 0, 800); pause = new Button(PAUSE); stepButton = new Button(STEP); setLayout(new BorderLayout()); add("South", speedBar); Panel btns = new Panel(); btns.add(new Button(START)); btns.add(new Button(STOP)); btns.add(pause); btns.add(stepButton); add("North", btns); } public boolean handleEvent(Event event) { if (event.target == speedBar) { parent.delay = 815 - speedBar.getValue(); return true; } else { return super.handleEvent(event); } } //determine what to do when button pushed public boolean action(Event ev, Object arg){ String label = (String)arg; if (label.equals(START)){ parent.restartAnim(); stepButton.hide(); } else if (label.equals(STOP)){ parent.killAnim(); } else if (label.equals(PAUSE)){ parent.stop(); pause.setLabel(RESTART); stepButton.show(); } else if (label.equals(RESTART)){ parent.restartAnim(); pause.setLabel(PAUSE); stepButton.hide(); } else if (label.equals(STEP)){ parent.stepAnim(); } return true; } //return pause button to "pause" state public void reset(){ pause.setLabel(PAUSE); } }