首先做一道改錯題吧。
下面的程序是個簡化的彈珠游戲。每按一下 Start 按鈕,就從左上角彈出一個球,并開始在球框中運動和彈跳。界面如下:
圖1
但運行下面的程序,你會發現一旦按了Start 按鈕,整個界面就像死機一樣,球不動,對界面的任何操作也無反應。這肯定不是程序想要的效果。為什么會這樣呢?要怎么辦呢?
源代碼
下載地址:http://m.tkk7.com/Files/jeff-lau/bounce_nothread.zip
/**
* @(#) Bounce.java 2007-12-31
*
* Copyright? 2007 Jeff. 該源代碼遵循BSD開源協議。
*/
package joj.thread.swing.bounce.nothread;
import javax.swing.JFrame;
/**
* 這是Bounce程序的啟動類。
*
* @since 5.0
* @author Jeff
*/
public class Bounce {
/**
* 程序啟動函數。
*
* @param args
* 不理睬該參數
*/
public static void main(String[] args) {
JFrame frame = new BounceFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
/**
* @(#) BounceFrame.java 2007-12-31
*
* Copyright? 2007 Jeff. 該源代碼遵循BSD開源協議。
*/
package joj.thread.swing.bounce.nothread;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Bounce程序的主窗體
*
* @author Jeff
*
*/
@SuppressWarnings("serial")
public class BounceFrame extends JFrame {
private static final int DEFAULT_HEIGHT = 300;
private static final int DEFAULT_WIDTH = 400;
private BallPanel ballPanel;
public BounceFrame() throws HeadlessException {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
add(getBallPanel(), BorderLayout.CENTER);
add(getButtonPanel(), BorderLayout.SOUTH);
}
private Component getBallPanel() {
if (ballPanel == null) {
ballPanel = new BallPanel();
}
return ballPanel;
}
private Component getButtonPanel() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(getStartButton());
buttonPanel.add(getCloseButton());
return buttonPanel;
}
private Component getStartButton() {
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
addBall();
}
});
return startButton;
}
private Component getCloseButton() {
JButton closeButton = new JButton("Close");
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
return closeButton;
}
private void addBall() {
Ball ball = ballPanel.addBall();
try {
for (int i = 0; i < 1000; i++) {
ball.move(ballPanel.getBounds());
ballPanel.paintComponent(ballPanel.getGraphics());
Thread.sleep(3);
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
/**
* @(#) BallPanel.java 2007-12-31
*
* Copyright? 2007 Jeff.
* 該源代碼遵循BSD開源協議。
*/
package joj.thread.swing.bounce.nothread;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class BallPanel extends JPanel {
private List balls = new ArrayList();
public Ball addBall() {
Ball ball = new Ball();
balls.add(ball);
return ball;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Ball ball : balls) {
g2.fill(ball.getShape());
}
}
}
/**
* @(#) Ball.java 2007-12-31
*
* Copyright? 2007 Jeff. 該源代碼遵循BSD開源協議。
*/
package joj.thread.swing.bounce.nothread;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
public class Ball {
private double left = 0;
private double top = 0;
private double width = 15;
private double height = 15;
private double dx = 5;
private double dy = 5;
public Shape getShape() {
return new Ellipse2D.Double(left, top, width, height);
}
public void move(Rectangle2D bounds) {
left += dx;
top += dy;
if (left < bounds.getMinX()) {
left = bounds.getMinX();
dx = -dx;
}
if (left + width > bounds.getMaxX()) {
left = bounds.getMaxX() - width;
dx = -dx;
}
if (top < bounds.getMinY()) {
top = bounds.getMinY();
dy = -dy;
}
if (top + height > bounds.getMaxY()) {
top = bounds.getMaxY() - height;
dy = -dy;
}
}
}
posted on 2007-12-31 22:00
Jeff Lau 閱讀(367)
評論(0) 編輯 收藏 所屬分類:
跟老劉學Java