0

我正在尝试使用多线程来绘制在 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();
}
}

球跟踪器

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();
}
}

球架

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 );
}
}
4

2 回答 2

1

我主要是在寻找与我在这里尝试绘制的方式有关的问题,以及为什么我看不到球

  1. 球未添加到任何面板。
  2. 即使您确实将球添加到面板中,球也没有大小,因此没有可绘制的内容。
  3. 即使您确实为面板指定了大小,也只有一个 Ball 会出现,因为您的 Ball 面板是不透明的。
  4. 您的代码正在尝试在球面板内的某个位置绘制球。相反,您应该在球面板内的位置 (0, 0) 处绘制球,然后设置 Ball 面板相对于父容器的位置。
  5. 父容器应该使用空布局,以便您可以随机设置 Ball 面板的位置。

我敢肯定还有其他问题...

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

于 2013-05-19T22:50:04.317 回答
1

似乎您的球扩展了 jpanel 并具有绘画方法,但是您的 ballPanel 需要进行绘画,而您的球似乎根本不需要成为面板。

set up ball panel
ballPanel = new JPanel();
ballPanel.setSize(WIDTH, 500);
于 2013-05-19T22:47:05.203 回答