好吧,我正在尝试使用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没有停止每一圈。
编辑:谢谢你们所有人!答案 0 :(得分:6)
你遇到的问题是你的代码在GUI线程上运行,这就是与GUI对话并将其呈现给屏幕的问题。您调用该方法来设置图标,但实际上并没有重绘屏幕,它只是对事物进行排队,以便在下一次GUI线程获得空闲时刻时重新绘制屏幕。但是你让GUI线程休眠一秒钟,在此期间它无法做任何事情。在整个方法完成之前,它将无法更新屏幕上的任何内容,此时您已完成所有图标更新和所有睡眠!
答案是使用javax.swing.Timer
将setIcon()
次呼叫排队,以便在固定间隔后发生。 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
}
}