java - 在 Java 中将线程对象添加到 JPanel

标签 java multithreading swing

我正在尝试使用 addBall 方法用它自己的线程将球绘制到 colorBallPanel

我非常困惑,非常感谢任何帮助。

顺便说一句,我正在尝试制作弹跳球程序,其中所有球都在自己单独的线程上运行。

public class ColoredBallPanel extends JPanel
{
    Ball ball;
    public ColoredBallPanel()
    {
        ball= new Ball();
    }
    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, 499, 300);
//      ball.paint(g2);

    }
}


import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
public class BallsFrame extends JFrame
{
     private ColoredBallPanel coloredBallPanel;
     private final int FRAME_WIDTH = 500;
     private final int FRAME_HEIGHT = 500;
     private int BallDimensionsx =30,BallDimensionsy=30;
     private Ball ball = new Ball();
     public BallsFrame()
     {
         //sets the size of the JFrame
         setSize(FRAME_WIDTH, FRAME_HEIGHT);
         coloredBallPanel = new ColoredBallPanel();//Initialize a Ball panel
         add(coloredBallPanel, BorderLayout.CENTER);//white square in the centre
         addBall(); // add two balls to panel(Doesn't work yet)
         addBall();

     }

    public void addBall()
     {
        Ball ball = new Ball();
         coloredBallPanel.add(ball);

         Runnable r = new ColoredBallRunnable(ball, coloredBallPanel);
         Thread t = new Thread(r);
         t.start();
     }



}





import java.awt.*;

import javax.swing.*;


public class Ball extends JComponent 
{
    private int x=(int) (Math.random()*(500 -1)),
                y =(int) (Math.random()*(300-1)),
                xVelocity=-10,
                yVelocity=10;
    private int width=30,height=30,size =30;
    /**
     * @param args
     */
    public void update()
    {
        x+=xVelocity;
        y+=yVelocity;
        if(x<=0)
        {
            xVelocity =10;
        }
        else if(x+size>=500)
        {
            xVelocity = -10;
        }
        if(y<=0)
        {
            yVelocity =10;
        }
        else if (y+size>=300)
        {
            yVelocity=-10;
        }
    }

    public void paint(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.GREEN);
        g2.fillOval(x, y, width, height);
    }


}

    import javax.swing.JComponent;
import javax.swing.JPanel;


public class ColoredBallRunnable implements Runnable 
{
    private Ball ball ;
    public ColoredBallRunnable(Ball ball, ColoredBallPanel coloredBallPanel)
    {
        // TODO Auto-generated constructor stub
         ball = new Ball();
        coloredBallPanel = new ColoredBallPanel();
    }


    public void run()
    {
        Ball ball = new Ball();
        while(true)
        {
        ball.update();
        ball.repaint();
        try{
            Thread.sleep(10);
        }catch(InterruptedException e){
            return;
        }
        }
    }

}

最佳答案

问题太多了...

  1. Ball组件是否已添加到 Container这是在 LayoutManager 的控制下,这意味着,即使你得到 Ball要移动,您将一直与布局管理器战斗
  2. Ball没有“大小”(或与此相关的位置),因此当将其添加到 Container 时,其大小调整为默认大小 0x0 ,使其几乎不可见
  3. Ball从来没有画过。这实际上有两个原因,但我们将从明显的开始,它不会覆盖任何允许 Swing 绘制它的有效绘制方法...如果它大于 0x0 .

解决方案...?

  • 制造Ball只是一个知道自己大小和位置的 POJO(如果需要的话可以自行更新)
  • 创建某种可以在 View 之间共享的“模型”ColoredBallPanel和 Controller (线程)。该模型应维护一个列表 Ball目前可用...
  • 允许 ColoredBallPanel循环遍历这个球列表并通过它的 paintComponent 绘制它们方法
  • 允许 Controller 循环遍历此球列表并更新它们。
  • 同步对球列表的访问,因此 View 或 Controller 在对方使用列表时都不会弄乱该列表。您可能会考虑为 View 创建列表的只读版本,但这可能超出了现在的范围......
  • 调用 super.paintComponent在进行任何自定义绘画之前

也许,更像 Java Bouncing Ball

关于java - 在 Java 中将线程对象添加到 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27413116/

相关文章:

c++ - 将多个参数传递给线程函数 c++11

java - 在 setVisible 后创建 JComboBox 使 JButton 消失

java - 错误的泛型转换没有 ClassCastException [Java]

java - Maven - maven-war-plugin 更改目标目录(webapp 除外)

java - 当我在项目中使用 volatile 时,为什么下面的代码显示不同的结果?

java - 如何找出谁破坏了 KEY_TYPED 事件?

java - 在 Java 中显示 TIFF 图像

java - JButtons AWT 控件 java

java - 带有 "is"前缀 getter 方法的 boolean 字段的 Hamcrest 断言

java - 同步数据结构