import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Ellipse2D; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.swing.JComponent; /** * This class represents a drawing surface that can draw bouncing balls. * When an action event is triggered on this canvas, it moves the balls * around; if done repeatedly at intervals, this produces animation. * @author Marty Stepp * @version CSE 331 Spring 2011, 05/18/2011 */ public class BallCanvas extends JComponent implements ActionListener { private static final long serialVersionUID = 1L; private static final int BALL_COUNT = 1000; private List balls; // all bouncing balls to draw /** * Constructs a new empty canvas with no lines. */ public BallCanvas() { balls = new ArrayList(); // produce lots of random bouncing balls Random randy = new Random(); for (int i = 0; i < BALL_COUNT; i++) { int red = randy.nextInt(255); int green = randy.nextInt(255); int blue = randy.nextInt(255); Ball ball = new Ball(randy.nextInt(100), randy.nextInt(200), randy.nextInt(40) + 10, randy.nextInt(11) - 5, randy.nextInt(11) - 5, new Color(red, green, blue)); balls.add(ball); } } /** * Handles action events (timer ticks) on this canvas by updating the position * of every ball on the screen. */ public void actionPerformed(ActionEvent event) { // this will be called every ~20ms for (Ball ball : balls) { ball.move(); if (ball.getX() < 0 || ball.getRightX() >= this.getWidth()) { ball.bounceLeftRight(); } if (ball.getY() < 0 || ball.getBottomY() >= this.getHeight()) { ball.bounceTopBottom(); } } repaint(); } /** * Draws all of the balls on this canvas at their given positions. */ public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; for (Ball ball : balls) { Ellipse2D ballLipse = new Ellipse2D.Double(ball.getX(), ball.getY(), ball.getSize(), ball.getSize()); g2.setPaint(ball.getColor()); g2.fill(ballLipse); } } }