如何在每圈之间制作for循环等待1秒?

时间:2014-09-19 20:04:46

标签: java swing animation

好吧,我正在尝试使用for循环创建一个小动画,代码是下一个:

private class Listen4 implements ActionListener{
    int i ;
    for (i = 0; i<5 ; i++){
            try{
                    if (i == 0){ imglabel.setIcon(new ImageIcon("1.png")); }
                    if (i == 1){ imglabel.setIcon(new ImageIcon("2.png")); }
                    if (i == 2){ imglabel.setIcon(new ImageIcon("1.png")); }
                    if (i == 3){ imglabel.setIcon(new ImageIcon("2.png")); }
                    if (i == 4){ imglabel.setIcon(new ImageIcon("1.png")); }
                    Thread.sleep(1000);
            }
            catch (InterruptedException e){}
     }
}

问题是当我执行程序时,图像不会改变;这让我觉得也许Thread没有停止每一圈。

编辑:谢谢你们所有人!

3 个答案:

答案 0 :(得分:6)

你遇到的问题是你的代码在GUI线程上运行,这就是与GUI对话并将其呈现给屏幕的问题。您调用该方法来设置图标,但实际上并没有重绘屏幕,它只是对事物进行排队,以便在下一次GUI线程获得空闲时刻时重新绘制屏幕。但是你让GUI线程休眠一秒钟,在此期间它无法做任何事情。在整个方法完成之前,它将无法更新屏幕上的任何内容,此时您已完成所有图标更新和所有睡眠!

答案是使用javax.swing.TimersetIcon()次呼叫排队,以便在固定间隔后发生。 Timer将启动一个新线程在后台等待适当的时间,然后它将调用GUI线程上的setIcon()调用。这是你可以做到的唯一方法:等待必须在后台,但GUI更新调用必须在GUI线程上。

试试这个:

int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        imglabel.setIcon(new ImageIcon("1.png"));
    }
};
new Timer(delay, taskPerformer).start();

还要注意,由于ActionListener是一个内部类,因此它不能引用imglabel,除非它是final字段(但这不应该是一个问题:你总是可以final)。

对于奖励分数,理想情况下,您不会从ImageIcon创建三个不同的1.png个实例:您只能创建一个,然后再使用它三次。

答案 1 :(得分:0)

问题是您的循环正在Event Dispatch Thread上运行,它负责在您更改图像时更新图像。因此,当您暂停当前时,您将停止事件调度线程,然后无法更新图像。

解决方案是创建一个单独的线程来运行循环,该循环向Event Dispatch Thread线程发送消息以更改映像。最简单的方法是使用javax.swing.Timer

答案 2 :(得分:0)

ActionLister al = new ActionListener() {
  public void actionPerformed(ActionEvent ae) {
    ... // You will have to keep a counter or check the image already in the label 
    //to know which one to switch it to
  }
}