java - 多线程弹跳球、显示球问题

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

球追踪器

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

最佳答案

看起来你的球扩展了 jpanel 并有一个绘制方法,但是你的 ballPanel 需要进行绘制,而你的球似乎根本不需要成为一个面板。

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

关于java - 多线程弹跳球、显示球问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16639936/

相关文章:

c - 产生新进程 v 线程的动机

java - JFrame 显示黑屏,右上角有一个白色的小矩形

java - JButton 设置 X 位置不起作用

java - 如何在 Swing 中创建单独的屏幕?

java - 如何对齐 JTextPane 中选定的文本?

java - 基于函数输入的线程 block

java - 如何将 UndoableEditListener 添加到 JTable 单元格?

java - 在java中每行10个整数之后开始新行的更有效方法是什么?

c# - 如何处理容易挂起当前线程的调用

java - CompletableFuture.allOf 在抛出异常时取消其他 future