我正在尝试将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);
}
}
}
答案 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()。这也有一个好处,就是你不能为每个球创建一个新线程,但只需要一个控制器线程。