class BallPanel
    extends JPanel {
  private ArrayList balls ;
  public BallPanel(){
    this.balls = new ArrayList();
    this.setFocusable(true);
    this.addMouseListener(new MouseAdapter(){
      public void mousePressed(MouseEvent event){
        moveBalls();
      }
    }
      );
  }
  public void addBall(Ball b) {
    this.balls.add(b);
  }  public void moveBalls() {
    if(balls.size()==0)
      return ;
    for (int i = 0; i < balls.size(); i++) {
      Ball b = (Ball) balls.get(i);
      b.move();
    }
    repaint();
  }  public void paintComponent(Graphics g) {
    super.paintComponents(g);
    Graphics2D g2 = (Graphics2D) g;
    System.out.println("size is :" + balls.size());
    for (int i = 0; i < balls.size(); i++) {
      Ball b = (Ball) balls.get(i);
      b.draw(g2);
    }
  }
}class Ball {
  private int x = 0;
  private int y = 0;
  private int xBound = 400;
  private int yBound = 400;
  public final int XSIZE = 10; //球宽度
  public final int YSIZE = 10; //球高度
  public int dx = 10;//横向位移距离
  public int dy = 10; //纵向位移距离
  public Ball(int x, int y, int xBound, int yBound) {
    this.x = x;
    this.y = y;
    this.xBound = xBound;
    this.yBound = yBound;
  }
  public void move() {
    x += dx;
    y += dy;
    if (x < 0) {
      x = 0;
      dx = -dx;
    }
    if (x + XSIZE >= xBound) {
      x = xBound - XSIZE;
      dx = -dx;
    }
    if (y < 0) {
      y = 0;
      dy = -dy;
    }
    if (y + YSIZE >= yBound) {
      y = yBound - YSIZE;
      dy = -dy;
    }
  }  public void draw(Graphics2D g2) {
    g2.fill(new Ellipse2D.Double(x, y, XSIZE, YSIZE));
  }
}class BallShowThread extends Thread{
  private BallPanel bPanel;
  public BallShowThread(BallPanel bPanel){
    this.bPanel = bPanel;
  }
  public void run(){
    try {
      for(int i=0;i<1000;i++){
        this.bPanel.moveBalls();
        Thread.sleep(5);
      }
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

解决方案 »

  1.   

    看了半天,头大
    我觉得你应该在
        repaint();
    前面将前面的小球清除掉现在的结果是这个小球的运行痕迹
      

  2.   

    public void moveBalls() {
        if(balls.size()==0)
          return ;
        for (int i = 0; i < balls.size(); i++) {
    //for (int i = 0; i < 1; i++) {
          Ball b = (Ball) balls.get(i);
          b.move();
        }
    //updateUI();
    //paint();
        repaint();
      }  public void paintComponent(Graphics g) {
        super.paintComponents(g);
        Graphics2D g2 = (Graphics2D) g;
        System.out.println("size is :" + balls.size());
        for (int i = 0; i < balls.size(); i++) {
          Ball b = (Ball) balls.get(i);
          b.draw(g2);
        }
      }目前肯定这段代码有问题
      

  3.   

    public void run(){
        try {
          for(int i=0;i<1000;i++){
            this.bPanel.moveBalls();
            repaint();------------------------------加上这句
            Thread.sleep(5);
          }
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }
      }  能达到你要的效果,每次移动球时要去掉以前的球的轨迹
      

  4.   

    继续实验了一下,关键问题在你要repaint的是container c,而不是bPanel
      

  5.   

    我又把刚才加的repaint去掉, 把moveBalls中的repaint去掉改为c.repaint(),当然这时候要把Container c = this.getContentPane();放到上一层括号中去,并把class ball作为public class的内部类。    也可以达到要求的效果。   所以证明你需要repaint的是c而不是bPanel
      

  6.   

    x.clearRect(int,int ,int,int);擦掉轨迹
      

  7.   

    非常感谢 alickma(零缺点)的回复,实践证明你的做法是正确的。
    但是,我想不明白为什么。
     
      

  8.   

    这个我也不太清楚,但是上面两个说的用clearRect应该是可以的,待会有时间我试一下
      

  9.   

    但是,运行起来,确实有问题。
    请高手指点原理,为什么alickma(零缺点)的办法可行。
      

  10.   

    我也想知道原因,而且一直以来就觉得repaint这个东西怪怪的,必须实践才知道是什么效果,而且一般与想象的有区别
      

  11.   

    你的代码有问题!class Ball {

    //-----记录小球的原始位置--------
    private int xOld = 0;
    private int yOld = 0;

    private int x = 0;
    private int y = 0;
    private int xBound = 400;
    private int yBound = 400;
    public final int XSIZE = 10; //球宽度
    public final int YSIZE = 10; //球高度
    public int dx = 10;//横向位移距离
    public int dy = 10; //纵向位移距离
    public Ball(int x, int y, int xBound, int yBound) {
    this.x = x;
    this.y = y;
    this.xBound = xBound;
    this.yBound = yBound;
    }
    public void move() {
    //--记录小球的原始位置----
    xOld = x;
    yOld = y;

    x += dx;
    y += dy;
    if (x < 0) {
    x = 0;
    dx = -dx;
    }
    if (x + XSIZE >= xBound) {
    x = xBound - XSIZE;
    dx = -dx;
    }
    if (y < 0) {
    y = 0;
    dy = -dy;
    }
    if (y + YSIZE >= yBound) {
    y = yBound - YSIZE;
    dy = -dy;
    }
    }

    public void draw(Graphics2D g2) {
    // 擦除原来位置上的小球
    g2.setXORMode(g2.getBackground());
    g2.fill(new Ellipse2D.Double(xOld, yOld, XSIZE, YSIZE));

    // 重画新位置的小球
    g2.fill(new Ellipse2D.Double(x, y, XSIZE, YSIZE));
    }
    }
    这个用这个 class Ball 替换你的 原来的Ball。这段代码还有问题,主要是 xOld,yOld
    记录的值,有时候不是小球的上一此出现的坐标,你调试调试,原理就是这样的。