有两个类
BirdThread 利用线程不断画图
Cage 提供frame
程序只在开始调用了paint()
 run()中的repaint()没有调用paint()
怎样才能让repaint()调用paint()???
 import java.awt.*;
 import java.awt.event.*; public class BirdThread extends Canvas implements Runnable{
   private Thread birdThread=null;
   private int xdir=(1-2*(int)Math.round(Math.random()));
   private int ydir=(1-2*(int)Math.round(Math.random()));
   private Cage cage=null;
   protected int x,y;
   Image bird=Toolkit.getDefaultToolkit().getImage("bird.jpg");
   
   public BirdThread(Cage _cage,int _x,int _y)
   {
    cage=_cage;
    x=_x;
    y=_y;//System.out.println("o");
   }
   
   public void start()
   {
    if(birdThread==null)
         {
            birdThread=new Thread(this);
            birdThread.start();
       }//System.out.println("start");
   }
   
   public void stop()
   {
     birdThread=null; 
   }   public void run()
   {
     Thread currentThread=Thread.currentThread();
     while(birdThread==currentThread)
     {
      move();
      this.repaint();
      try{
         birdThread.sleep(120);
       }catch(InterruptedException ie){
          System.err.println("Thread interrupted");       
        }     
       //System.out.println("run");
       
     } 
   }
   
   public void move()
   {
    x+=xdir;
    y+=ydir;
    if(x<0||x>cage.getSize().width) xdir=-xdir;
    if(y<0||y>cage.getSize().height) ydir=-ydir;
    //System.out.println("move");
   }
   
   public void paint(Graphics g)
   {
    g.drawImage(bird,x,y,30,30,this);
    //System.out.println("paint");
   } }
 -----------------------------
 import java.awt.*;
 import java.awt.event.*; public class Cage extends Frame implements ActionListener{
  private Button quit=new Button("Quit");
  private Button start=new Button("Start");
  private Button stop=new Button("Stop");
  private BirdThread birds[]=new BirdThread[20];
    
  
  
  public Cage()
  {
   super("Cage with birds");
   
   Panel buttons=new Panel();
   buttons.setLayout(new FlowLayout());
     buttons.add(quit); quit.addActionListener(this);
   buttons.add(start); start.addActionListener(this);
   buttons.add(stop); stop.addActionListener(this);
   
   setLayout(new BorderLayout());
   add("South",buttons);
   //validate();
   //pack();   for(int i=0;i<birds.length;i++)
   {
   int x=(int)(getSize().width*Math.random());
   int y=(int)(getSize().width*Math.random());
   birds[i]=new BirdThread(this,x,y);
     add("Center",birds[i]); 
   
   }
   setSize(500,500);
   setVisible(true);   
  }
  
  public void actionPerformed(ActionEvent ae)
  {
   if(ae.getSource()==quit)
     System.exit(0);
   if(ae.getSource()==start)
    for(int i=0;i<birds.length;i++)
    {
     birds[i].stop();
     birds[i]=new BirdThread(this,birds[i].x,birds[i].y);
     birds[i].start();
    }
   if(ae.getSource()==stop)
      for(int i=0;i<birds.length;i++)
        birds[i].stop();
         
     
  }
  public static void main(String args[])
  {
   Cage cage=new Cage();
   //System.out.println(cage.toString());
  }
   }

解决方案 »

  1.   

    一开始上手就不要搞这么复杂的吧主要问题是 birds[] 相互覆盖,所以把你 事件里面的:
            if (ae.getSource() == start)
                for (int i = 0; i < birds.length; i++) {
                    //birds[i].stop(); // 注释掉
                    //birds[i] = new BirdThread(this, birds[i].x, birds[i].y); // 注释掉
                    birds[i].start();
                }再试试看,大致理解了吧?
    另外,paint里面可以直接先画点字符串,比如:
    g.drawString("A", x, y);
      

  2.   


    这样改了是有效果,但是只有一个bird线程运行,画了一个图片
    我想让20个bird线程运行怎么改
      

  3.   

    你20个Bird(Canvas)都叠在一起,互相覆盖,基本是看不到了。
    你试试看就知道我是啥意思了:
        public BirdThread(CSDN_Cage _cage, int _x, int _y) {
            this.setBackground(Color.red); // 增加这句话
            cage = _cage;
      

  4.   

    所以总的来说根本没必要用Canvas,直接在 Frame 的 paint 函数中,重绘20只鸟就行了;线程只需要负责改变鸟的坐标即可。
      

  5.   


    Cage中的构造函数是会导致每个bird的x,y都为0,因为getSize()得到的是0,
    把setSize()写到getSize以前,这样每个线程都会得到不同的x,y。然后根据x,y
    绘图,的到的图像位置就不同。但是只绘出了一个图像。
    好像线程之间会影响,绘出的是最后线程的图像
      

  6.   

    解决了
    不同线程中的canva绘图会被后一个线程覆盖掉,因为canvas一直填充超过frame
    我又写个BirdCanvas只负责画图,paint()一次性把20个图画完