import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * AnimationPanel.java * * An AnimationPanel is responsible for two things. First, it needs * to know at all times how to draw the current picture. As the * images/frames of the animation go by, the AnimationPanel knows * everything there is to know about the current image. Thus, any * time we explicitly call paint or the JVM's event thread calls * paint, paint will draw the current image of the animation. * * Second, the AnimationPanel is responsible for knowing how to * advance the animation from the current image to the next image. * AnimationPanel's step method knows how to move the Ball and adjust * the Ball's velocity if a bounce is needed. (Whether this * knowledge should be stored here or in some other class is an * interesting design question. For our short-term purposes, I have * left this knowledge in AnimationPanel for simplicity.) */ public class AnimationPanel extends JPanel { private Ball ball; public AnimationPanel() { super(); } public void setBall(Ball b) { ball = b; } public Ball getBall() { return ball; } public void step() { // Move the ball and draw it. ball.step(); repaint(); // Adjust the velocity in preparation for the next step of the animation. int vx = ball.getVelocityX(); int vy = ball.getVelocityY(); Dimension panelSize = getSize(); if (ball.getX() - ball.getRadius() < 0 || ball.getX() + ball.getRadius() > panelSize.width) { vx = -vx; } if (ball.getY() - ball.getRadius() < 0 || ball.getY() + ball.getRadius() > panelSize.height) { vy = -vy; } ball.setVelocity(vx, vy); } public void paint(Graphics g) { // Fill the panel with the background color. That is, // erase the whole thing. // // Note that we are not calling JPanel's default version // of paint, which allows us to control everything about // the paint operation. (In my experiments, replacing the // following three lines with "super.paint(g);" produces // the same behavior, however.) Dimension size = getSize(); g.setColor(getBackground()); g.fillRect(0, 0, size.width, size.height); // Draw the Ball. ball.draw(g); } }