1、缺少对象,gg传入ball中时为空
在init中加一句:
gg=getGraphics();2、线程只执行了一次,所以只会画一个圆,应该在run中加上while(true)完整程序如下:
import java.applet.Applet;
import javax.swing.JApplet;
import java.awt.*;class ball  implements Runnable{
int x,y;//position
int r;//size
int delay;
Graphics gg;
public ball(int a,int b,int c,int d,Graphics f)
{
x=a;
y=b;
r=c;
delay=d;
gg=f;
}

public void run()
{
while(true) /////////////////////////////////
try
{
Thread.sleep(delay);
if(r>=150) r=10;
r+=5;
this.paint(gg);
}catch(InterruptedException e){e.printStackTrace();}
}

public void paint(Graphics g)
{
g.drawOval(x+r,y+r,50+r,50+r);
g.setColor(Color.red);
g.fillOval(x+r,y+r,50+r,50+r);

}

}
public class th extends Applet{
Thread [] th;
int delay;
int number;
Graphics gg;
int []length_move;
Color []colors;
int [][]positions;
public void init()
{
gg=this.getGraphics();       /////////////////////
this.setBackground(Color.black);
super.setSize(500,500);
if(getParameter("delay")==null)
{
delay = 1000;
}
else
{
delay = Integer.parseInt(getParameter("delay"));
}
if(getParameter("number")==null)
{
number=5;
}
else
{
number = Integer.parseInt(getParameter("number"));
}
th=new Thread[number];
int i;
for(i=0;i<number;i++)
{
th[i]=null;
}
length_move=new int[number];
for(i=0;i<number;i++) length_move[i]=i*5;
colors=new Color[number];
for(i=0;i<number;i++)
{
    switch(i%10)
    {case 1: colors[i]=Color.red;break;
    case 2: colors[i]=Color.blue;break;
    case 3: colors[i]=Color.MAGENTA;break;
    case 4: colors[i]=Color.yellow;break;
    default: colors[i]=Color.green; 
    }
      }
positions=new int[number][2];
int j=0;
for(i=0;i<number;i++)
  for(j=0;j<2;j++)
   {
    positions[i][j]=100*i;
   }

}

public void start()
{
for(int i=0;i<number;i++)
{
if(th[i]==null)
  th[i]=new Thread(new ball(positions[i][0],positions[i][1],length_move[i],delay,gg));
  th[i].start();
}
}

public void paint(Graphics g)
{
super.paint(g);
gg=g;
}

}3、好像画的时候应该清屏,不知道你程序本意如何。

解决方案 »

  1.   


    赫赫,交大第一英才来帮你解决问题唉,帮你改程序改得留鼻血。
    上面的那位大侠的改动为什么不行?
    因为Applet是由多个线程来完成的。在Java中,任何一个Applet的 paint()和update()方法都是由绘图与事件处理线 程调用的,而Applet 主要的里程碑方法——init(),start(),stop()和destory() ——是由执行该Applet的应用调用的。
    Applet的repaint()方法总是异步工作,你调用repaint()时,实际上是将重绘请求放入绘图与事件处理线程,绘图与事件处理线程,相当于invokeLater()的作用。
    所以重绘的动作写在其它类,就象你所写的:
    ball类里的代码:
    g.drawOval(x+r,y+r,50+r,50+r);
    g.setColor(Color.red);
    g.fillOval(x+r,y+r,50+r,50+r);
    不可能由绘图与事件处理线程调用。
    所以应该把它写在Applet的paint()里面。然后其它类调用repaint()以请求重绘。
    完整的代码是这样写的:package paintovi041123;import java.applet.Applet;
    import javax.swing.JApplet;
    import java.awt.*;class ball
        implements Runnable {
      int x, y; //position
      int r; //size
      int delay;
      Graphics gg;
      MyA app;
      Color color;
      public ball(int a, int b, int c, int d, Graphics f, MyA the_app,
                  Color the_color) {    x = a;
        y = b;
        r = c;
        delay = d;
        gg = f;
        color = the_color;
        app = the_app;
      }  public void run() {
        try {
          while (true) {
            Thread.sleep(20);
            if (r >= 150) {
              r = 10;
              Thread.sleep(delay);
            }
            r += 5;
            this.paint(gg);
          }
        }
        catch (InterruptedException e) {}
      }  public void paint(Graphics g) {
        app.x = x;
        app.y = y;
        app.r = r;
        app.appColor = this.color;
        app.repaint();  }}public class MyA
        extends Applet {
      Thread[] th;
      int delay;
      int number;
      Graphics gg;
      int[] length_move;
      Color[] colors;
      int[][] positions;
      public int x, y; //position
      public int r; //size
      int started = 0;
      public Color appColor;  public void init() {
        this.setBackground(Color.black);
        super.setSize(500, 500);    if (getParameter("number") == null) {
          number = 5;
        }
        else {
          number = Integer.parseInt(getParameter("number"));
        }
        if (getParameter("delay") == null) {
          delay = 300 * number;
        }
        else {
          delay = Integer.parseInt(getParameter("delay"));
        }    th = new Thread[number];
        int i;
        for (i = 0; i < number; i++) {
          th[i] = null;
        }
        length_move = new int[number];
        for (i = 0; i < number; i++) {
          length_move[i] = i * 5;
        }
        colors = new Color[number];
        for (i = 0; i < number; i++) {
          switch (i % 10) {
            case 1:
              colors[i] = Color.red;
              break;
            case 2:
              colors[i] = Color.blue;
              break;
            case 3:
              colors[i] = Color.MAGENTA;
              break;
            case 4:
              colors[i] = Color.yellow;
              break;
            default:
              colors[i] = Color.green;
          }
        }
        positions = new int[number][2];
        int j = 0;
        for (i = 0; i < number; i++) {
          for (j = 0; j < 2; j++) {
            positions[i][j] = 30 * i;
          }
        }  }  public void start() {
        for (int i = 0; i < number; i++) {
          if (th[i] == null) {
            th[i] = new Thread(new ball(positions[i][0], positions[i][1],
                                        length_move[i], delay, gg, this,
                                        this.colors[i]));
            th[i].start();
            try {
              Thread.currentThread().sleep(300);
            }
            catch (InterruptedException ex1) {
              ex1.printStackTrace();
            }
          }
        }
      }  public void paint(Graphics g) {
        if (started == 0) {
          ++started;    }
        g.setColor(this.appColor);
        g.fillOval(x + r, y + r, 50 + r, 50 + r);  }}
      

  2.   

    果然是第一英才
    没几日就将java研究那么深入,值得学习。
    有几事不明:
    1、照阁下程序,ball类中根本不需要Graphics gg,去掉完全可以,是不是不符合英才优化原则。
    2、本人不才程序中通过
    gg=this.getGraphics();
    获取applet的grahpics再传入ball类中,实际也是在applet上画图,有何不对了?为啥说不行?如果说没有清屏,那我承认没做。
    3、人家要画6个圆,英才的程序满眼是圆,眼拙没看出是几个。
      

  3.   

    1、照阁下程序,ball类中根本不需要Graphics gg,去掉完全可以,是不是不符合英才优化原则。
    2、本人不才程序中通过
    gg=this.getGraphics();
    获取applet的grahpics再传入ball类中,实际也是在applet上画图,有何不对了?为啥说不行?如果说没有清屏,那我承认没做。
    ---------------------------------------------------------------------------------repaint()的机制不是直接在applet窗口上画图,它的内部运行可以描述成这样:
    public void repaint()
    {
           绘图与事件处理线程.队列.Add("call for paint()");
    }
    绘图与事件处理线程是JVM定义的,专门负责重绘,也——只有它能够重绘——,当绘图与事件处理线程处理完队列中在"call for paint()"之前的所有请求之后,它就处理"call for paint()",这时它才调用paint()。
    所以,
    public void paint(Graphics g)
    {
    g.drawOval(x+r,y+r,50+r,50+r);
    g.setColor(Color.red);
    g.fillOval(x+r,y+r,50+r,50+r);
    }
    绕过了绘图与事件处理机制,看似合理但事实上不行。
    这也是applet落后的地方,它会复杂化一些关于界面的逻辑。--------------------------------------------
    (Graphics gg我是忘了注释掉了)
      

  4.   

    3、人家要画6个圆,英才的程序满眼是圆,眼拙没看出是几个。------------------------------------------------------------------------------------我以为六个圆是交替出现的,原来楼主的用意是同时出现的,那就写成这样:package paintovi041123;import java.applet.Applet;
    import javax.swing.JApplet;
    import java.awt.*;class ball
        implements Runnable {
      int x, y; //position
      int r; //size
      int delay;
      int index;
      Graphics gg;
      MyA app;
      Color color;
      public ball(int a, int b, int c, int d, Color theColor, MyA the_app,
                  int the_index) {    x = a;
        y = b;
        r = c;
        delay = d;
        color = theColor;
        app = the_app;
        index = the_index;
      }  public void run() {
        try {
          while (true) {
            Thread.sleep(delay);
            if (r >= 150) {
              r = 10;
            }
            r += 5;
            this.paint(gg);
          }
        }
        catch (InterruptedException e) {}
      }  public void paint(Graphics g) {
        app.repaint();
      }}public class MyA
        extends Applet {
      
      int delay;
      int number;
      int[] length_move;
      int[][] positions;
      ball[] ballvars;
      
      //Thread[] th;
      //Graphics gg;
      //Color[] colors;  public void init() {
        this.setBackground(Color.black);
        super.setSize(500, 500);    if (getParameter("number") == null) {
          number = 6;
        }
        else {
          number = Integer.parseInt(getParameter("number"));
        }
        if (getParameter("delay") == null) {
          delay = 25;
        }
        else {
          delay = Integer.parseInt(getParameter("delay"));
        }    int i;
      
        length_move = new int[number];
        for (i = 0; i < number; i++) {
          length_move[i] = i * 5;
        }    positions = new int[number][2];
        int j = 0;
        for (i = 0; i < number; i++) {
          for (j = 0; j < 2; j++) {
            positions[i][j] = 30 * i;
          }
        }    this.ballvars = new ball[number];
        Color the_color;    for (int i1 = 0; i1 < number; i1++) {
          switch (i1 % 10) {
            case 1:
              the_color = Color.red;
              break;
            case 2:
              the_color = Color.blue;
              break;
            case 3:
              the_color = Color.MAGENTA;
              break;
            case 4:
              the_color = Color.yellow;
              break;
            case 5:
              the_color = Color.orange;
              break;
            default:
              the_color = Color.green;
              break;
          }      if (this.ballvars[i1] == null) {
            this.ballvars[i1] = new ball(positions[i1][0], positions[i1][1],
                                         length_move[i1], delay, the_color, this,
                                         i1);
          }
        }  }  public void start() {    for (int i1 = 0; i1 < number; i1++) {
          
            Thread thread = new Thread(this.ballvars[i1]);
            thread.start();
          
        }
      }  public void paint(Graphics g) {    for (int i = 0; i < this.number; ++i) {
          g.setColor(this.ballvars[i].color);
          g.fillOval(this.ballvars[i].x + this.ballvars[i].r,
                     this.ballvars[i].y + this.ballvars[i].r,
                     50 + this.ballvars[i].r, 50 + this.ballvars[i].r);
        }  }}
    另外还有什么问题都可以跟我讨论。
      

  5.   

    上面有点小疏忽:ball类的paint(Graphics g)可以改成paint(),仓鼠应该去掉。
      

  6.   

    承认的你程序更合理些,而且分析的也是合理的。我只是不想让楼主的程序变动太大,所以将applet的graphics传入ball中
    实际上ball中本没有paint(Graphics g)方法的(和applet不一样),相当于自定义了一个
    所以是显示调用的,
    this.paint(gg);关系如下:
    (g)applet-->(gg)ball-->paint(gg)在ball中调用的paint(gg)
    相当于调用
    applet中的paint(g);如果将ball中的paint(Graphics g)方法换成什么DrawBall(Graphics g)可能就不容易混淆了
    所以实际我的程序和你程序运行机制基本是一样的。不知道你运行过我的程序没有?
    其中public void paint(Graphics g)
    改写如下:(加了一个清屏)
    public void paint(Graphics g)
    {
    g.setColor(Color.black);
    g.fillOval(x+r-5,y+r-5,50+r-5,50+r-5);
    g.setColor(Color.red);
    g.fillOval(x+r,y+r,50+r,50+r);
    }你的程序我也运行过了,是一个线程同时画6个圆
    不知道楼主何意
    我理解是一个线程管一个圆。
      

  7.   

    我也改了一下,你们也可以看看,只有5个圆吧~~~
    // <applet code=th width=200 height=100></applet>
    import java.applet.Applet;
    import javax.swing.JApplet;
    import java.awt.*;class ball  implements Runnable{
    int x,y;//position
    int r;//size
    int delay;
    Color cc,//所画圆的颜色,我见你后面的colors数组赋值的那么辛苦而没有用到,
            //我想你本意应该是要用的,所以帮你加上
          bColor;//背景颜色,清屏用的。
    Graphics gg;
    public ball(int a,int b,int c,Color color,Color BColor,int d,Graphics f)
    {
    x=a;
    y=b;
    r=c;
    cc=color;
    bColor = BColor;
    delay=d;
    gg=f;
    }public void run()
    {
    while(true) /////////////////////////////////
    try
    {
    this.paint(gg,bColor);       //用背景色填充上次所画的圆,即清屏
    if(r>=150) r=10;
    r+=5;
    this.paint(gg,cc);
    Thread.sleep(delay);         //放在这里才能看清所画的圆。
    }catch(InterruptedException e){e.printStackTrace();}
    }public void paint(Graphics g,Color pColor)   //增加一个颜色的参数
    {
    // g.drawOval(x+r,y+r,50+r,50+r);  不需要
    g.setColor(pColor);
    g.fillOval(x+r,y+r,50+r,50+r);
    }}
    public class th extends Applet{
    Thread [] th;
    int delay;
    int number;
    Graphics gg;
    int []length_move;
    Color []colors;
    Color bColor=Color.black;    //背景颜色
    int [][]positions;
    public void init()
    {
    gg=this.getGraphics();       /////////////////////
    this.setBackground(bColor);
    super.setSize(500,500);
    if(getParameter("delay")==null)
    {
    delay = 1000;
    }
    else
    {
    delay = Integer.parseInt(getParameter("delay"));
    }
    if(getParameter("number")==null)
    {
    number=5;
    }
    else
    {
    number = Integer.parseInt(getParameter("number"));
    }
    th=new Thread[number];
    int i;
    for(i=0;i<number;i++)
    {
    th[i]=null;
    }
    length_move=new int[number];
    for(i=0;i<number;i++) length_move[i]=i*5;
    colors=new Color[number];
    for(i=0;i<number;i++)
    {
       switch(i%10)
       {case 1: colors[i]=Color.red;break;
        case 2: colors[i]=Color.blue;break;
        case 3: colors[i]=Color.MAGENTA;break;
        case 4: colors[i]=Color.yellow;break;
        default: colors[i]=Color.green; 
        }
    }
    positions=new int[number][2];
    int j=0;
    for(i=0;i<number;i++)
      for(j=0;j<2;j++)
      {
       positions[i][j]=100*i;
      }}public void start()
    {
    for(int i=0;i<number;i++)
    {
    if(th[i]==null)
      th[i]=new Thread(new ball(positions[i][0],positions[i][1],length_move[i],colors[i],bColor,delay,gg));
      th[i].start();
    }
    }//public void paint(Graphics g)    没必要
    //{
    //super.paint(g);
    //gg=g;
    //}}
      

  8.   

    楼上两位当然正确,我只想表达一种不同的思路。import java.applet.Applet;
    import javax.swing.JApplet;
    import java.awt.*;class ball
        implements Runnable {
      int x, y;
      int r; 
      int delay;
      int index;
      MyA app;
      Color color;
      public ball(int a, int b, int c, int d, Color theColor, MyA the_app,
                  int the_index) {    x = a;
        y = b;
        r = c;
        delay = d;
        color = theColor;
        app = the_app;
        index = the_index;
      }  public void run() {
        try {
          while (true) {
            Thread.sleep(delay);
            if (r >= 150) {
              color = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
              r = 10;
            }
            r += 5;
            app.repaint();
          }
        }
        catch (InterruptedException e) {}
      }
    }public class th
        extends Applet {
      
      int delay;
      int number;
      int[] length_move;
      int[][] positions;
      ball[] ballvars;  public void init() {
        this.setBackground(Color.black);
        super.setSize(500, 500);    if (getParameter("number") == null) {
          number = 6;
        }
        else {
          number = Integer.parseInt(getParameter("number"));
        }
        if (getParameter("delay") == null) {
          delay = 100;
        }
        else {
          delay = Integer.parseInt(getParameter("delay"));
        }    int i;
      
        length_move = new int[number];
        for (i = 0; i < number; i++) {
          length_move[i] = i * 5;
        }    positions = new int[number][2];
        int j = 0;
        for (i = 0; i < number; i++) {
          for (j = 0; j < 2; j++) {
            positions[i][j] = 30 * i;
          }
        }    this.ballvars = new ball[number];
        Color the_color;
        for (int i1 = 0; i1 < number; i1++) {
         
         the_color = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
          if (this.ballvars[i1] == null) {
            this.ballvars[i1] = new ball(positions[i1][0], positions[i1][1],
                                         length_move[i1], delay, the_color, this,
                                         i1);
          }
        }  }  public void start() {    for (int i1 = 0; i1 < number; i1++) {
          
            Thread thread = new Thread(this.ballvars[i1]);
            thread.start();
          
        }
      }  public void paint(Graphics g) {    for (int i = 0; i < this.number; ++i) {
          g.setColor(this.ballvars[i].color);
          g.fillOval(this.ballvars[i].x + this.ballvars[i].r,
                     this.ballvars[i].y + this.ballvars[i].r,
                     this.ballvars[i].r,  this.ballvars[i].r);
        }  }}
      

  9.   

    呵呵,这里真热闹啊!
    谢谢你们的回复,我是学java才10天啦,所以有一些结构不会是最优的。总之就是谢谢
      

  10.   

    斗胆敢问migthline(交大的Hejlsberg) :JAVA是不是也只学了2个月?