多线程弹跳球,发出显示球

时间:2013-05-19 22:03:12

标签: java multithreading swing awt

我正在尝试使用多线程来绘制在JFrame内部反弹的球。我可以让每个球的坐标更新并打印出来,但是我无法显示球。我的图形不是很强,我不太清楚我缺少什么。我想我需要将Ball的每个实例添加到我框架内的面板中,但是当我尝试它时没有任何区别。我还有一个用于查看JFrame的类,我已经省略了。我在这里缺少什么?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;

public class Ball extends JPanel implements Runnable  {
JPanel pan;
private static int radius = 10;
private Color color;
private int xPos;
private int yPos;
private int dx;
private int dy;
Dimension d;

public Ball(JPanel p) {
    Random r = new Random();
    this.pan = p;
    this.d = pan.getSize();
    xPos = r.nextInt(d.width-50)+25;
    yPos = r.nextInt(d.height-50)+25;
    dx = r.nextInt(3)+1;
    dy = r.nextInt(3)+1;
    color = new Color(r.nextInt(255*255*255));
    paintComponent(pan.getGraphics());
}

public void move() {
    xPos += dx;
    yPos += dy;
    if (xPos+radius <= 0 || xPos+radius >= d.width)
        dx = -dx;
    if (yPos+radius <= 0 || yPos+radius >= d.height)
        dy = -dy;
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(color);
    g.fillOval(xPos-radius, yPos-radius, 2*radius, 2*radius);
    g.dispose();
}

public void animate() {
    paintComponent(pan.getGraphics());
    move();
    //pan.validate();//this didn't
    //pan.repaint();// work
    try {
        Thread.sleep(40);
    } catch (InterruptedException e) {}
}

public void run() {
    while(true)
        animate();
}
}

BallTracker

import java.util.ArrayList;

public class BallTracker {
private ArrayList<Ball> balls;

public BallTracker() {
    balls = new ArrayList<Ball>();
}

public void addBall(Ball b) {
    balls.add(b);
    Thread t = new Thread(b);
    t.start();
}
}

BallFrame

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BallFrame extends JFrame {
public static final int WIDTH = 500;
public static final int HEIGHT = 550;
private BallTracker tracker;
private JPanel ballPanel;
private JPanel buttonPanel;

public BallFrame() {
    super("BallFrame");
    tracker = new BallTracker();

    // set up ball panel
    ballPanel = new JPanel();
    ballPanel.setSize(WIDTH, 500);

    // listener to add a new ball to tracker
    class bListener implements ActionListener {
        public void actionPerformed( ActionEvent event ) {
            Ball b = new Ball(ballPanel);
            tracker.addBall(b);

        }
    }

    // set up button panel
    buttonPanel = new JPanel();
    buttonPanel.setSize(WIDTH, 50);
    JButton addBallButton = new JButton();
    addBallButton.setText("Add ball");
    addBallButton.addActionListener(new bListener());
    buttonPanel.add(addBallButton);

    // add panels to frame
    add(buttonPanel, BorderLayout.SOUTH);
    add(ballPanel, BorderLayout.CENTER);
    setSize( WIDTH, HEIGHT );
}
}

2 个答案:

答案 0 :(得分:1)

看起来你的球延伸了jpanel并且有一个绘画方法,但你的ballPanel需要做绘画,你的球似乎根本不需要是一个面板。

set up ball panel
ballPanel = new JPanel();
ballPanel.setSize(WIDTH, 500);

答案 1 :(得分:1)

  

我主要是在寻找我在这里画画的方式的问题,以及为什么我没有看到球

  1. 球未添加到任何面板。
  2. 即使你把球添加到面板上,球也没有尺寸,所以没有什么可以画的。
  3. 即使您确实给面板一个尺寸,也只会出现一个Ball,因为Ball面板是不透明的。
  4. 您的代码正试图在球面板内的某个位置绘制球。相反,您应该在球面板中的位置(0,0)处绘制球,然后设置球面板相对于父容器的位置。
  5. 父容器应使用空布局,以便您可以随机设置Ball面板的位置。
  6. 我确信还有其他问题......

    我建议你忘记多线程并从自定义绘画和使用计时器的基础开始。