阅读和修改一个球的代码程序,完成多球的功能:
Write a program that bounces balls inside a panel.The ball should begin moving with a mousePressed event. When user clocks the mouse, a ball should be added. When balls hits the edge of the panel,it should bounde off the edge and continue in the opposite direction.
The ball location should be updated using Runnable.
GUI as follows:
程序如下:
import java.util.Random;
public class Ball implements Runnable {
private int x; // horizontal position of ball
private int y; // vertical position of ball
private int dx; // change in horizontal position of ball
private int dy; // change in vertical position of ball
private final int MAX_X = 200; // horizontal edge of JPanel
private final int MAX_Y = 200; // vertical edge of JPanel
private static final Random generator = new Random();
public Ball(int xPos, int yPos) {
dx = generator.nextInt(5) + 1; // change in x (1-5 pixels)
dy = generator.nextInt(5) + 1; // change in y (1-5 pixels)
x = xPos; // set ball to horizontal position of mouse press
y = yPos; // set ball to vertical position of mouse press
}
// bounces ball perpetually until window is closed
public void run() {
while (true) {// infinite loop {
try {
Thread.sleep(20); // sleep for 20 milliseconds
}
// process InterruptedException during sleep
catch (InterruptedException exception) {
exception.printStackTrace();
}
x += dx; // determine new x-position
y += dy; // determine new y-position
// if bounce off top or bottom of JPanel
if (y <= 0 || y >= MAX_Y - 10) {
dy = -dy; // reverse velocity in y direction
}
// if bounce off left or right of JPanel
if (x <= 0 || x >= MAX_X - 10) {
dx = -dx; // reverse velocity in x direction
}
}
}
// get horizontal position of ball
public int getX() {
return x; // return x value
}
// get vertical position of ball
public int getY() {
return y; // return y value
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class BallPanel extends JPanel {
private Ball blueBall; // bouncing ball
private ExecutorService threadExecutor; // for running Ball runnable
private JFrame parentWindow; // parent window of JPanel
private final int MAX_X = 200; // horizontal edge of JPanel
private final int MAX_Y = 200; // vertical edge of JPanel
public BallPanel(JFrame window) {
parentWindow = window; // set parent window of JPanel
// create ExecutorService for running ball runnable
threadExecutor = Executors.newCachedThreadPool();
// anonymous inner class handles mouse events
this.addMouseListener(
new MouseAdapter() {
public void mousePressed(MouseEvent event) {
createBall(event); // delegate call to ball starter
RepaintTimer timer = new RepaintTimer(parentWindow);
threadExecutor.execute(timer);
}
}
);
}
// create a ball if no ball exists and set it in motion
private void createBall(MouseEvent event) {
if (blueBall == null) {// if no ball exists {
int x = event.getX(); // get x position of mouse press
int y = event.getY(); // get y position of mouse press
blueBall = new Ball(x, y); // create new ball
threadExecutor.execute(blueBall); // set ball in motion
}
}
// return minimum size of animation
public Dimension getMinimumSize() {
return getPreferredSize();
}
// return preferred size of animation
public Dimension getPreferredSize() {
return new Dimension(MAX_X, MAX_Y);
}
// draw ball at current position
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (blueBall != null) {// if ball exists {
g.setColor(Color.blue); // set color to blue
g.fillOval(blueBall.getX(), blueBall.getY(), 10, 10); // draws
}
}
}
import javax.swing.JFrame;
public class BouncingBall extends JFrame {
private final BallPanel ballCanvas; // JPanel in which ball bounces
public BouncingBall() {
ballCanvas = new BallPanel(this); // create new BallPanel
add(ballCanvas); // add BallPanel to JFrame
pack(); // make window just large enough for its GUI
setVisible(true); // show window
}
public static void main(String args[]) {
BouncingBall application = new BouncingBall();
application.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
import javax.swing.JFrame;
public class RepaintTimer implements Runnable {
private final JFrame repaintComponent;
public RepaintTimer(JFrame frame) {
// specify component to be repainted
repaintComponent = frame;
}
public void run() {
while (true) {
try {
Thread.sleep(20);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
repaintComponent.repaint(); // repaint the component
}
}
}