rollenholt的博文:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html
弹球例子:
0. 创建Bounce框架 JFrame frame = new BounceFrame();
BounceFrame自定义了addButton、addBall方法,用于在frame内的panel添加按钮、小球
1. 设置标题 setTitle("bounce");
2. 创建BallComponent comp = new Ballcomponent();
BallComponent继承于JPanel。专门用于容纳并绘制Ball
3. 将comp添加到框架frame
4. 创建JPanel buttonPanel = new JPanel();用于存放start、close按钮
5. 创建start、close按钮,并添加到buttonPanel中
6. 将buttonPanel添加到框架frame
代码:
Bounce.java
public class Bounce { public static void main(String args[]){ EventQueue.invokeLater(new Runnable(){ public void run(){ JFrame frame = new BounceFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } } class BallRunnable implements Runnable{ private Ball ball; private Component component; public static final int STEPS =2000; public static final int DELAY = 5 ; public BallRunnable(Ball ball , Component component){ this.ball=ball; this.component = component; } public void run(){ try { for(int i = 0 ; i < STEPS ; i++){ ball.move(component.getBounds()); //移动小球 //repaint会激活component的paintComponent方法 component.repaint(); Thread.sleep(DELAY); } }catch(InterruptedException e){ //处理异常 } } } class BounceFrame extends JFrame{ private BallComponent comp; public BounceFrame(){ setTitle("Bounce"); comp = new BallComponent(); add(comp,BorderLayout.CENTER); JPanel buttonPanel = new JPanel(); addButton(buttonPanel,"Start",new ActionListener(){ public void actionPerformed(ActionEvent e){ addBall(); } }); addButton(buttonPanel , "Close" , new ActionListener(){ public void actionPerformed(ActionEvent e){ System.exit(0); } }); add(buttonPanel,BorderLayout.SOUTH); pack(); } public void addButton(Container c, String title , ActionListener listener){ JButton button = new JButton(title); c.add(button); button.addActionListener(listener); } public void addBall(){ try{ Ball ball = new Ball(); comp.add(ball); Runnable r = new BallRunnable(ball,comp); Thread t = new Thread(r); t.start(); }catch(Exception e){ //处理异常 } } }
Ball.java
package com.thread.Multithreadball; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; public class Ball { private static final int XSIZE = 15; private static final int YSIZE = 15; private double x = 0; private double y = 0; private double dx = 1; private double dy = 1; public void move(Rectangle2D bounds){ x += dx; y += dy; if(x<bounds.getMinX()){ x=bounds.getMinX(); dx=-dx; } if(x + XSIZE >= bounds.getMaxX()){ x=bounds.getMaxX()-XSIZE; dx=-dx; } if(y<bounds.getMinY()){ y=bounds.getMinY(); dy=-dy; } if(y + YSIZE >= bounds.getMaxY()){ y = bounds.getMaxY() - YSIZE; dy=-dy; } } //获取当前的小球 public Ellipse2D getShape(){ return new Ellipse2D.Double(x,y,XSIZE,YSIZE); } }
BallComponent.java
public class BallComponent extends JPanel{ private static final int DEFAULT_WIDTH = 450; private static final int DEFAULT_HEIGHT = 350; private List<Ball> balls = new ArrayList<>(); //将一个球加入到component public void add(Ball b ){ balls.add(b); } public void paintComponent (Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; for(Ball b : balls){ g2.fill(b.getShape()); } } public Dimension getPreferredSize(){ return new Dimension(DEFAULT_WIDTH,DEFAULT_HEIGHT); } }