Introduction
A Simple Animation
Adding a Scrollbar (end of class 2/10/98)
Adding Buffering
An External Animation Thread
Applet Summary
Next Topic: Object Oriented Programming Concepts
/* < Applet code = MoveIt width = 300 height = 300 > < /Applet > */ import java.applet.*; import java.awt.*; import java.awt.event.*; public class MoveIt extends Applet implements ActionListener, Runnable { Button StartButton; int init_x = 50; int init_y = 50; int rect_width = 50; int rect_height = 20; int x; int y; int num = 100; Thread move_thread; public void init() { setBackground(Color.lightGray); setLayout(new BorderLayout()); StartButton = new Button("Start"); add("South",StartButton); StartButton.addActionListener(this); x = init_x; y = init_y; } public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(x,y,rect_width,rect_height); } public void stop() { if (move_thread != null) move_thread.suspend(); } public void start() { if (move_thread != null) move_thread.resume(); } public void run() { try { for(int i=0;i < num;i++) { x++; y++; repaint(1); Thread.sleep(100); } } catch (InterruptedException e) { return; // end this thread } } public void actionPerformed(ActionEvent e) { if (e.getSource() == StartButton) { x = init_x; y = init_y; move_thread = new Thread(this); move_thread.start(); } } }Click Here to run MoveIt.
/* < Applet code = MoveItSB width = 300 height = 300 > < /Applet > */ import java.applet.*; import java.awt.*; import java.awt.event.*; public class MoveItSB extends Applet implements ActionListener, AdjustmentListener, Runnable { Button StartButton; int init_x = 50; int init_y = 50; int rect_width = 50; int rect_height = 20; int x; int y; int num = 100; int delay = 100; Thread move_thread; Label DelayLabel; Scrollbar DelayValue; public void init() { Panel p = new Panel(); Panel q = new Panel(); p.setLayout(new GridLayout(2,1)); q.setLayout(new GridLayout(1,2)); setBackground(Color.lightGray); setLayout(new BorderLayout()); StartButton = new Button("Start"); DelayLabel = new Label("Delay "+delay); q.add(DelayLabel); DelayValue = new Scrollbar(Scrollbar.HORIZONTAL,delay,10,0,1010); DelayValue.addAdjustmentListener(this); q.add(DelayValue); p.add(q); p.add(StartButton); add("South",p); StartButton.addActionListener(this); x = init_x; y = init_y; } public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(x,y,rect_width,rect_height); } public void stop() { if (move_thread != null) move_thread.suspend(); } public void start() { if (move_thread != null) move_thread.resume(); } public void run() { try { for(int i=0;i < num;i++) { x++; y++; repaint(1); Thread.sleep(delay); } } catch (InterruptedException e) { return; // end this thread } } public void actionPerformed(ActionEvent e) { if (e.getSource() == StartButton) { x = init_x; y = init_y; move_thread = new Thread(this); move_thread.start(); } } public void adjustmentValueChanged(AdjustmentEvent e) { delay = DelayValue.getValue(); DelayLabel.setText("Delay "+delay); } }Click Here to run MoveItSB.
/* & lt Applet code = MoveItDB width = 300 height = 300 > < /Applet > */ import java.applet.*; import java.awt.*; import java.awt.event.*; public class MoveItDB extends Applet implements ActionListener, AdjustmentListener, Runnable { Button StartButton; int init_x = 50; int init_y = 50; int rect_width = 50; int rect_height = 20; int x; int y; int num = 100; int delay = 100; Thread move_thread; Label DelayLabel; Scrollbar DelayValue; Image buffer; Graphics GC; Graphics GCback; int width; int height; public void init() { Panel p = new Panel(); Panel q = new Panel(); p.setLayout(new GridLayout(2,1)); q.setLayout(new GridLayout(1,2)); setBackground(Color.lightGray); setLayout(new BorderLayout()); StartButton = new Button("Start"); DelayLabel = new Label("Delay "+delay); q.add(DelayLabel); DelayValue = new Scrollbar(Scrollbar.HORIZONTAL,delay,10,0,1010); DelayValue.addAdjustmentListener(this); q.add(DelayValue); p.add(q); p.add(StartButton); add("South",p); StartButton.addActionListener(this); x = init_x; y = init_y; width = getBounds().width; height = getBounds().height; buffer = createImage(width,height); GC = buffer.getGraphics(); GCback = buffer.getGraphics(); GC.setColor(Color.red); GCback.setColor(Color.yellow); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { GCback.fillRect(0,0,width,height); GC.fillRect(x,y,rect_width,rect_height); g.drawImage(buffer,0,0,this); } public void stop() { if (move_thread != null) move_thread.suspend(); } public void start() { if (move_thread != null) move_thread.resume(); } public void run() { try { for(int i=0;i < num;i++) { x++; y++; repaint(1); Thread.sleep(delay); } } catch (InterruptedException e) { return; // end this thread } } public void actionPerformed(ActionEvent e) { if (e.getSource() == StartButton) { x = init_x; y = init_y; move_thread = new Thread(this); move_thread.start(); } } public void adjustmentValueChanged(AdjustmentEvent e) { delay = DelayValue.getValue(); DelayLabel.setText("Delay "+delay); } }Click Here to run MoveItDB.
import java.applet.*; import java.awt.*; import java.awt.event.*; public class SimpleAnimationThread extends Thread { private int num; private int delay; private Applet ap; private Point pos; public SimpleAnimationThread(Point init_pos, int num, int delay, Applet ap) { pos = new Point(init_pos); this.num = num; this.delay = delay; this.ap = ap; } public Point GetPosition() { return pos; } public void run() { try { for(int i=0;i < num;i++) { pos.x++; pos.y++; ap.repaint(1); Thread.sleep(delay); } } catch (InterruptedException e) { } } }
/* < Applet code = MoveItExt width = 300 height = 300 > < /Applet > */ import java.applet.*; import java.awt.*; import java.awt.event.*; public class MoveItExt extends Applet implements ActionListener, AdjustmentListener { Button StartButton; int init_x = 50; int init_y = 50; int rect_width = 50; int rect_height = 20; int num = 100; int delay = 100; SimpleAnimationThread move_thread; Label DelayLabel; Scrollbar DelayValue; Image buffer; Graphics GC; Graphics GCback; int width; int height; Point init_pos; public void init() { Panel p = new Panel(); Panel q = new Panel(); p.setLayout(new GridLayout(2,1)); q.setLayout(new GridLayout(1,2)); setBackground(Color.lightGray); setLayout(new BorderLayout()); StartButton = new Button("Start"); DelayLabel = new Label("Delay "+delay); q.add(DelayLabel); DelayValue = new Scrollbar(Scrollbar.HORIZONTAL,delay,10,0,1010); DelayValue.addAdjustmentListener(this); q.add(DelayValue); p.add(q); p.add(StartButton); add("South",p); StartButton.addActionListener(this); init_pos = new Point(init_x,init_y); width = getBounds().width; height = getBounds().height; buffer = createImage(width,height); GC = buffer.getGraphics(); GCback = buffer.getGraphics(); GC.setColor(Color.red); GCback.setColor(Color.yellow); } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { Point pt; GCback.fillRect(0,0,width,height); if (move_thread == null) pt = init_pos; else pt = move_thread.GetPosition(); GC.fillRect(pt.x,pt.y,rect_width,rect_height); g.drawImage(buffer,0,0,this); } public void stop() { if (move_thread != null) move_thread.suspend(); } public void start() { if (move_thread != null) move_thread.resume(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == StartButton) { move_thread = new SimpleAnimationThread(init_pos, num, delay, this); move_thread.start(); } } public void adjustmentValueChanged(AdjustmentEvent e) { delay = DelayValue.getValue(); DelayLabel.setText("Delay "+delay); } }Click Here to run this applet.
Click Here to run the applet with this change.
Look at SimpleAnimationThread. In what ways can the coordinates represented by pos change?
Suggest a change to SimpleAnimationThread.
How would these classes have to be changed to allow two rectangles to move independently?
MoveItSB add a scrollbar for determining the delay between frames.
MoveItDB adds buffering to avoid flicker.
MoveItExt is a version that uses an external thread.
MoveItExt1 is a slight change which shows why it it necessary to be careful when passes objects to methods.