首先做一道改错题吧。
下面的程序是个简化的弹珠游戏。每按一下 Start 按钮,就从左上角弹出一个球,并开始在球框中运动和弹跳。界面如下:
图1
但运行下面的程序,你会发现一旦按了Start 按钮,整个界面就像死机一样,球不动,对界面的任何操作也无反应。这肯定不是程序想要的效果。为什么会这样呢?要怎么办呢?
源代码
下载地址:http://www.blogjava.net/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