初始化现有对象

时间:2014-10-22 18:55:12

标签: java multithreading object global-variables

我正在尝试将paintcall全局变量初始化为已存在的ballGUI对象。我必须这样做才能在我的run函数中为多线程调用repaint方法,这样就不会为每个单独的球做出新的GUI。进口空间用于空间。

import java.awt.Color;

public class BallT extends Thread implements Runnable {

  private static int xcord, ycord, ychange, xchange;
  private static boolean xUp;
  private static boolean yUp;
  private Color color;
  private BallGUI paintcall=//? existing object BallGUI ;

  public BallT(int x, int y) {
    yUp = false;
    xUp = false;
    xcord = x;
    ycord = y;
    color = new Color((int) Math.random(), (int) Math.random(),
        (int) Math.random());
  }

  public Color getColor() {
    return color;
  }

  public int getX() {
    return xcord;
  }

  public int getY() {
    return ycord;
  }

  public void run() {
    while (true) {
      try {
        Thread.sleep(50);
      } catch (InterruptedException e) {
      }
      if (xUp == true) {
        xcord = xcord + xchange;
      } else {
        xcord = xcord - xchange;
      }
      if (yUp == true) {
        ycord = ycord + ychange;
      } else {
        ycord = ycord - ychange;
      }
      if (xcord <= 0) {
        xUp = true;
        xchange = (int) Math.random() * 5;
      } else if (xcord > 340) {
        xUp = false;
        xchange = (int) Math.random() * 5;
      }
      if (ycord <= 0) {
        yUp = true;
        ychange = (int) Math.random() * 5;
      } else if (ycord > 340) {
        yUp = false;
        ychange = (int) Math.random() * 5;
      }
      paintcall.repaint();
    }

  }

}



@SuppressWarnings("serial")
public class BallGUI extends JFrame {

  public JPanel ballappear;
  private final int maxBalls = 20;
  private BallT[] balls;
  private int count;
  private ExecutorService threadPool = Executors.newCachedThreadPool();

  public BallGUI() {
    super("Bouncing");
    ballappear = new JPanel();
    count = 0;
    balls = new BallT[20];
    addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        makeBall(e);
      }
    });
    add(ballappear);

  }

  private void makeBall(MouseEvent e) {
    if (count < maxBalls - 1) {
      int x = e.getX();
      int y = e.getY();
      balls[count] = new BallT(x, y);
      threadPool.execute(balls[count]);
      count++;
    }

  }

  @Override
  public void paint(Graphics g) {
    super.paint(g);
    for (int i = 0; i < count; i++) {
      g.setColor(Color.BLACK);
      g.fillOval(balls[i].getX(), 340, 10, 10);
      g.setColor(balls[i].getColor());
      g.fillOval(balls[i].getX(), balls[i].getY(), 10, 10);
    }
  }

}

1 个答案:

答案 0 :(得分:0)

首先是简单的解决方案 - 更改BallT构造函数以获取BallGUI实例:

public BallT(int x, int y, BallGUI ballGUI) {
    this.paintcall = ballGUI;
    yUp = false;
    //...

接下来,在构建期间传入GUI对象中的实例:

private void makeBall(MouseEvent e) {
    if (count < maxBalls - 1) {
        // ...
        balls[count] = new BallT(x, y, this);
    }
}

然而,根据良好的模型 - 视图 - 控制器(MVC)设计实践,这是回到了前面。通常,视图(BallGUI)应该知道模型(BallT),但模型应该不知道视图。你的BallGUI已经保留了一个BallT列表,它可能是在paint()方法中查询的。我会考虑让一个Controller负责依次调用每个BallT上的updatePosition()方法,然后在GUI上调用repaint()。这也有一个好处,就是你不能为每个球创建一个新线程,但只需要一个控制器线程。