paint()方法不接受Java中的更新变量

时间:2014-07-04 21:33:11

标签: java swing jframe

我正在尝试将ArrayList Cars内部生成的汽车绘制到tryCar()方法中,当我调用System.out.println(Cars.size());时,它会打印出适当的大小但是一旦我尝试在paint()方法中绘制它无法识别它。 这是我的代码。 r是来自Random()

java.util.Random
public void Update(){
    if(r.nextInt(100)>85){
        tryCar();
    }
}

void tryCar(){
    if(r.nextBoolean()){
        Car c = new Car(r.nextInt(2), r.nextInt(6)+6, r.nextBoolean());
        Cars.add(c);
        cars++;
        System.out.println(Cars.size());
    }
}

public void paint(Graphics g) {
    super.paint(g);
    this.setVisible(true);
    this.setBackground(Color.BLACK);
    Road.drawLvl(g);
    System.out.println(Cars.size());
    g.fillRect(p1.X,p1.Y,p1.W,p1.H);
    for(int i = 0; i<Cars.size(); i++){ 
        System.out.println("s");
        Car c = (Car) Cars.get(i);
        g.setColor(new Color((r.nextInt(2)*255),(r.nextInt(2)*255),(r.nextInt(2)*255)));
        g.fillRect(c.X,c.Y,c.W,c.H);
    }
}

以下是整个班级:

public class Game extends JPanel {
private static final long serialVersionUID = 1L;
int CARS = 20;
int cars = 0;
ArrayList Cars = new ArrayList();
Player p1 = new Player(20,20);
Environment Road = new Environment(1);
Random r = new Random();
public void Update(){
    System.out.println("c");
    if(r.nextInt(100)>85){
        System.out.println("e");
        tryCar();
    }
    p1.Move(Main.c);
}
void tryCar(){
    if(r.nextBoolean()){
        System.out.println("v");
        Car c = new Car(r.nextInt(2), r.nextInt(6)+6, r.nextBoolean());
        Cars.add(c);
        cars++;
            System.out.println(Cars.size());
    }
}

public void paint(Graphics g) {
    super.paint(g);
    this.setVisible(true);
    this.setBackground(Color.BLACK);
    Road.drawLvl(g);
    g.setColor(new Color(255,0,0));
    //      System.out.println(p1.X);
    System.out.println(Cars.size());
    g.fillRect(p1.X,p1.Y,p1.W,p1.H);
    for(int i = 0; i<Cars.size(); i++){ 
        System.out.println("s");
        Car c = (Car) Cars.get(i);
        g.setColor(new Color((r.nextInt(2)*255),(r.nextInt(2)*255),(r.nextInt(2)*255)));
        g.fillRect(c.X,c.Y,c.W,c.H);
    }
}

}

2 个答案:

答案 0 :(得分:1)

让我们从Swing图像反弹不是线程安全的事实开始,这意味着在大多数情况下,UI的任何更新都应该在事件调度线程的上下文中完成

为此,通常,javax.swing.Timer是调度需要修改UI状态的常规回调的首选机制

此外,重新绘制主窗口可能不足以导致子组件重新绘制。

在您的链接代码示例中,您可以从repaint方法调用update,这里的危险是您可能在绘制组件时对状态进行修改,从而导致不一致输出。

这就是我推荐使用javax.swing.Timer的原因,因为它允许您在EDT的上下文中更新状态(也负责执行绘画更新),这意味着它(附近)国家不可能同时更新和绘画

作为一般规则,Swing组件应覆盖paintComponent以执行自定义绘制

答案 1 :(得分:-1)

通过Update方法将汽车添加到汽车中。如果在paint中,数组为空,那是因为没有Car添加到Cars。因此,只需确保调用Update方法,否则数组将始终为空 - 除非您直接修改数组而不是Update