随笔-16  评论-50  文章-2  trackbacks-0

首先做一道改错题吧。

下面的程序是个简化的弹珠游戏。每按一下 Start 按钮,就从左上角弹出一个球,并开始在球框中运动和弹跳。界面如下:

bounce 
图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 阅读(362) 评论(0)  编辑  收藏 所属分类: 跟老刘学Java

只有注册用户登录后才能发表评论。


网站导航: