java 多线程的练习,实现一个线程控制一个小球,多个小球在面板上运动的效果,主要包括4个类:
-
Ball类,用于保存一个小球的位置,实现移动小球的具体方法,返回小球的形状范围以便其他类使用这个形状来绘制小球。
-
BallPanel类,用于管理所有的小球,继承自Jpanel 类,重写了paintComponent方法,给出了面板重新绘制的具体操作。
-
BallThread类,用于管理单个小球的运动,线程的run方法主要操作是每过一定的时间就调用一下Ball 的move 方法,间隔很短,小球就好像运动的一样。
-
BallRun类,这是图像面板类,也是主类,用于启动和退出程序,同时也可以添加若干小球线程加入到面板中。
实现的效果图如下:
代码如下:
package ball;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Random;
class Ball{
private Double x;
private Double y;
private Double speedx;
private Double speedy;
private Rectangle2D bounds;
private Double radius;
public Ball(Double[] postion,Rectangle2D bounds){
this.x=postion[0];
this.y=postion[1];
this.bounds=bounds;
this.speedx=1.0;
this.speedy=1.0;
this.radius=20.0;
}
public void move(){
x+=speedx;
y+=speedy;
if(x<radius+bounds.getMinX()){
x=bounds.getMinX()+radius;
speedx=-speedx;
}
if(x+radius>=bounds.getMaxX()){
x=bounds.getMaxX()-radius;
speedx=-speedx;
}
if(y<radius+bounds.getMinX()){
y=bounds.getMinY()+radius;
speedy=-speedy;
}
if(y+radius>=bounds.getMaxY()){
y=bounds.getMaxY()-radius;
speedy=-speedy;
}
}
public Ellipse2D shape(){
return new Ellipse2D.Double(x,y,radius,radius);
}
}
class BallPanel extends JPanel{
private ArrayList<Ball> balls;
public BallPanel(){
this.balls=new ArrayList<Ball>();
this.setSize(1000,960);
}
public void add(Ball ball){
this.balls.add(ball);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics2D=(Graphics2D) g;
for(Ball ball:balls){
graphics2D.fill(ball.shape());
}
}
}
class BallThread extends Thread{
private Ball ball;
private BallPanel ballPanel;
private static Integer steps=4000;
public BallThread(Ball ball,BallPanel ballPanel){
this.ball=ball;
this.ballPanel=ballPanel;
}
@Override
public void run() {
for(int i=0;i<steps;i++){
ball.move();
ballPanel.repaint();
try {
Thread.sleep(5);
}catch (Exception e){}
}
}
}
public class BallRun {
private JFrame frame;
private BallPanel ballPanel;
private Double[] RandomPostion(){
Random random=new Random();
Double[] position=new Double[2];
position[0]=1000*random.nextDouble();
position[1]=1000*random.nextDouble();
return position;
}
public BallRun(){
this.frame=new JFrame("多线程小球");
frame.setSize(1000,1000);
ballPanel=new BallPanel();
JPanel buttonPanel=new JPanel();
JButton addBall=new JButton("添加");
JButton exitBtn=new JButton("退出");
addBall.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Ball ball=new Ball(RandomPostion(),ballPanel.getBounds());
ballPanel.add(ball);
BallThread thread=new BallThread(ball,ballPanel);
thread.start();
}
});
exitBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
buttonPanel.add(addBall);
buttonPanel.add(exitBtn);
frame.add(buttonPanel,BorderLayout.SOUTH);
frame.add(ballPanel,BorderLayout.CENTER);
frame.setVisible(true);
}
public static void main(String[] args) {
BallRun ballRun=new BallRun();
}
}