/* Copyright 1998, John C. Lahr */ import java.applet.*; import java.awt.*; /** * An applet that displays a simple animation using double-buffering * and clipping **/ public class niag extends Applet implements Runnable { Dimension size; // The size of the applet Image buffer; // The off-screen image for double-buffering protected Image niag; // Picture of Niagara Falls protected MediaTracker tracker; Graphics bufferGraphics; // A Graphics object for the buffer Thread animator; // Thread that performs the animation boolean please_stop; // A flag asking animation thread to stop int x1 = 160; int x2 = 230; int ymin = 80; int linespace = 15; int nincrements = 5; int increment = linespace/nincrements; int number_of_lines = 10; int ict; int ymax = ymin+linespace*number_of_lines; int section = 1; int frame_delay = 25; int duration = 2000; int nloops = duration/frame_delay; Button repeat_button; Button speedup_button; /** Set up an off-screen Image for double-buffering */ public void init() { repeat_button = new Button("Repeat at same speed"); this.add(repeat_button); speedup_button = new Button("Speed up"); this.add(speedup_button); tracker = new MediaTracker(this); String file = "niag.jpg"; niag = this.getImage(this.getDocumentBase(), file); tracker.addImage(niag, 1); size = this.size(); buffer = this.createImage(size.width, size.height); bufferGraphics = buffer.getGraphics(); } /** Draw frame, lines, or image depending on the value of section **/ public void paint(Graphics g) { // Draw into the off-screen buffer. // Note, we could do even better clipping by setting the clip rectangle // of bufferGraphics to be the same as that of g. // In Java 1.1: bufferGraphics.setClip(g.getClip()); if (section == 1) { bufferGraphics.setColor(Color.white); bufferGraphics.fillRect(0, 0, size().width, size().height); bufferGraphics.setColor(Color.red); bufferGraphics.drawRect(x1-1, ymin-1, x2-x1+2, ymax-ymin+2); bufferGraphics.setColor(Color.black); bufferGraphics.drawString( "Focus your view on the center of the rectangle", 70, 60); bufferGraphics.drawString("Speed = " + nloops, 70, 75); // Now copy the off-screen buffer onto the screen g.drawImage(buffer, 0, 0, this); } if (section == 2) { bufferGraphics.setColor(Color.white); bufferGraphics.fillRect(x1, ymin, x2-x1, ymax-ymin); bufferGraphics.setColor(Color.black); int y = ymax - ict*increment; for (int j = 0; j < number_of_lines; j++) { bufferGraphics.drawLine(x1, y, x2, y); y -= linespace; } // Now copy the off-screen buffer onto the screen g.drawImage(buffer, 0, 0, this); } if (section == 3) { bufferGraphics.drawImage(niag, 70, 50, this); g.drawImage(buffer, 0, 0, this); } } /** Don't clear the screen; just call paint() immediately * It is important to override this method like this for double-buffering */ public void update(Graphics g) { paint(g); } /** The body of the animation thread */ public void run() { section = 1; repaint(0, 0, size().width, size().height); try {Thread.sleep(250);} // Pause xx ms catch (InterruptedException e) {;} section = 2; for (int k = 1; k < nloops; k++) { for (ict = 0; ict < nincrements; ict++) { repaint(x1+1, ymin+1, x2-x1-2, ymax-ymin-2); try {Thread.sleep(frame_delay);} // Pause xx ms catch (InterruptedException e) {;} } } section = 3; repaint(); animator = null; } /** Start the animation thread */ public void start() { if (animator == null) { please_stop = false; animator = new Thread(this); animator.start(); } } /** Stop the animation thread */ public void stop() { please_stop = true; } /** Repeat at same speed **/ public boolean action(Event e, Object arg) { if (e.target == repeat_button) { /* System.out.println("pressed repeat button"); */ start(); return true; } if (e.target == speedup_button) { /* System.out.println("pressed speedup button"); */ frame_delay = frame_delay - 5; if (frame_delay == 0) frame_delay = 25; nloops = duration/frame_delay; start(); return true; } return false; } }