我正在尝试将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);
}
}
}
答案 0 :(得分:1)
让我们从Swing图像反弹不是线程安全的事实开始,这意味着在大多数情况下,UI的任何更新都应该在事件调度线程的上下文中完成
为此,通常,javax.swing.Timer
是调度需要修改UI状态的常规回调的首选机制
此外,重新绘制主窗口可能不足以导致子组件重新绘制。
在您的链接代码示例中,您可以从repaint
方法调用update
,这里的危险是您可能在绘制组件时对状态进行修改,从而导致不一致输出。
这就是我推荐使用javax.swing.Timer
的原因,因为它允许您在EDT的上下文中更新状态(也负责执行绘画更新),这意味着它(附近)国家不可能同时更新和绘画
作为一般规则,Swing组件应覆盖paintComponent
以执行自定义绘制
答案 1 :(得分:-1)
通过Update
方法将汽车添加到汽车中。如果在paint
中,数组为空,那是因为没有Car添加到Cars。因此,只需确保调用Update
方法,否则数组将始终为空 - 除非您直接修改数组而不是Update
。