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

在Java中将线程对象添加到JPanel,java,multithreading,swing,Java,Multithreading,Swing,我正在尝试使用addBall方法将一个球用它自己的线绘制到彩色的BallPanel上 我被困住了,如果有任何帮助我都会感激的 顺便说一句,我正在尝试制作弹跳球程序,其中所有的球都在各自的线程上运行 public class ColoredBallPanel extends JPanel { Ball ball; public ColoredBallPanel() { ball= new Ball(); } public void paint

我正在尝试使用addBall方法将一个球用它自己的线绘制到彩色的BallPanel上

我被困住了,如果有任何帮助我都会感激的

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

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

}
公共类ColoredBallPanel扩展了JPanel
{
球;
公共彩色BallPanel()
{
球=新球();
}
公共组件(图形g)
{
图形2d g2=(图形2d)g;
g2.设置颜色(颜色为白色);
g2.fillRect(0,0499300);
//球形涂料(g2);
}
}
导入java.awt.BorderLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类BallsFrame扩展了JFrame
{
私人彩球面板彩球面板;
专用最终整数帧_宽度=500;
专用最终内部框架高度=500;
专用整数BallDimensionsx=30,BallDimensionsy=30;
私人球=新球();
公共BallsFrame()
{
//设置JFrame的大小
设置尺寸(框宽、框高);
coloredBallPanel=新建coloredBallPanel();//初始化球面板
添加(彩色BallPanel,BorderLayout.CENTER);//中间为白色正方形
addBall();//将两个球添加到面板(尚未工作)
addBall();
}
公共无效addBall()
{
球=新球();
彩色球面板。添加(球);
Runnable r=新的ColoredBallRunnable(球,coloredBallPanel);
螺纹t=新螺纹(r);
t、 start();
}
}
导入java.awt.*;
导入javax.swing.*;
公共类球扩展JC组件
{
私有int x=(int)(Math.random()*(500-1)),
y=(int)(Math.random()*(300-1)),
x速度=-10,
yVelocity=10;
私有整数宽度=30,高度=30,大小=30;
/**
*@param args
*/
公共无效更新()
{
x+=x速度;
y+=y线性度;
如果(x=500)
{
x速度=-10;
}
如果(y=300)
{
yVelocity=-10;
}
}
公共空间涂料(图g)
{
图形2d g2=(图形2d)g;
g2.设置颜色(颜色为绿色);
g2.椭圆形(x、y、宽度、高度);
}
}
导入javax.swing.JComponent;
导入javax.swing.JPanel;
公共类ColoredBallRunnable实现Runnable
{
私人舞会;
公共彩色球可运行(球、彩色球面板彩色球面板)
{
//TODO自动生成的构造函数存根
球=新球();
coloredBallPanel=新的coloredBallPanel();
}
公开募捐
{
球=新球();
while(true)
{
更新();
ball.repaint();
试一试{
睡眠(10);
}捕捉(中断异常e){
返回;
}
}
}
}

问题太多了

  • Ball
    是添加到由
    LayoutManager
    控制的
    容器中的组件,这意味着,即使你让
    Ball
    移动,你也会一直与布局管理器战斗
  • Ball
    没有“大小”(或位置),因此当它添加到
    容器中时,它的大小将调整为默认大小
    0x0
    ,使其实际上不可见
  • 从不上漆。这实际上有两个原因,但我们将从显而易见的开始,它不会覆盖任何允许Swing绘制它的有效绘制方法…如果它大于
    0x0
  • 解决方案

    • Ball
      制作成一个POJO,它知道它的大小和位置(如果您需要的话,它可以自我更新)
    • 创建某种类型的“模型”,可以在视图
      ColoredBallPanel
      和控制器(线程)之间共享。此模型应维护当前可用的
      Ball
      s列表
    • 允许
      ColoredBallPanel
      在球列表中循环,并通过其
      paintComponent
      方法对球进行绘制
    • 允许控制器循环浏览此球列表并更新它们
    • 同步对balls列表的访问,以便在另一方使用列表时,视图或控制器都不会弄乱列表。您可能会考虑为视图创建一个只读版本,但这可能超出了目前的范围…
    • 在进行任何自定义绘制之前,请调用
      super.paintComponent

    也许,更像

    ColoredBallRunnable
    类在哪里?考虑提供一个说明你的问题的方法。这将减少我在课堂上增加的混乱和更好的反应