/* * Adapted from an example by * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM) * Published By SunSoft Press/Prentice-Hall * * An application with multiple threads for the bouncing balls in a frame. */ import java.awt.*; import java.awt.event.*; public class BounceThread extends Frame implements ActionListener { private Canvas canvas; // the constructor initializes the frame to be a borderlayout // with a canvas in the center and // two buttons labelled Start and Close in the south public BounceThread() { setLayout(new BorderLayout()); setTitle("BounceThread"); canvas = new Canvas(); add(canvas, BorderLayout.CENTER); Panel p = new Panel(); Button b1 = new Button("Start"); b1.addActionListener(this); p.add(b1); Button b2 = new Button("Close"); b2.addActionListener(this); p.add(b2); add(p, BorderLayout.SOUTH); } // responds to the Start button by creating a new instance // of the BallTimes class and starting its thread // responds to the close button by exiting the application public void actionPerformed(ActionEvent evt) { if (evt.getActionCommand().equals("Start")) { Ball b = new Ball(canvas); b.start(); } else if (evt.getActionCommand().equals("Close")) System.exit(0); } // the main method creates an instance of this class and sets the // properties of the frame public static void main(String[] args) { Frame f = new BounceThread(); f.setSize(400, 300); f.setVisible(true); } } /* The Ball class is a subclass of Thread, so each instance inherits * thread methods start, stop, sleep, etc. * The run method of the thread loops to draw a ball in a new location * for a fixed number of iterations. */ class Ball extends Thread { private Canvas box; private static final int XSIZE = 10; private static final int YSIZE = 10; private int x = 0; private int y = 0; private int dx = 2; private int dy = 2; // the constructor initializes the canvas to that of the frame public Ball(Canvas c) { box = c; } // draws the ball in the current location public void draw() { Graphics g = box.getGraphics(); g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } // increments the location of the ball, checks the boundary to see // if it should "bounce", and draws the ball // (uses XOR graphics to draw over previous location in the background // color.) public void move() { Graphics g = box.getGraphics(); g.setXORMode(box.getBackground()); g.fillOval(x, y, XSIZE, YSIZE); x += dx; y += dy; Dimension d = box.getSize(); if (x < 0) { x = 0; dx = -dx; } if (x + XSIZE >= d.width) { x = d.width - XSIZE; dx = -dx; } if (y < 0) { y = 0; dy = -dy; } if (y + YSIZE >= d.height) { y = d.height - YSIZE; dy = -dy; } g.fillOval(x, y, XSIZE, YSIZE); g.dispose(); } // loops for 1000 times and moves the ball public void run() { draw(); for (int i = 1; i <= 1000; i++) { move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } } }