Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用计时器更改JLabel中的ImageIcon_Java_Swing_Timer_Jbutton_Imageicon - Fatal编程技术网

Java 使用计时器更改JLabel中的ImageIcon

Java 使用计时器更改JLabel中的ImageIcon,java,swing,timer,jbutton,imageicon,Java,Swing,Timer,Jbutton,Imageicon,我有两个类:逻辑和JFrame。在框架中,我有一个JLabel和一个JButton,我想: 单击此按钮时,标签中的ImageIcon会在使用Swing计时器的确定时间后更改,就像它在闪烁一样。为此,我加载了两个亮度不同的图像(img1b和img1)。我试图让计时器以不同的延迟更改图像两次,但没有成功。我还在按钮中放置了一个侦听器,并实现了actionPerformed,如下所示: public void actionPerformed(ActionEvent e) { if(e.getS

我有两个类:逻辑和
JFrame
。在框架中,我有一个
JLabel
和一个
JButton
,我想:

单击此按钮时,标签中的
ImageIcon
会在使用Swing
计时器的确定时间后更改,就像它在闪烁一样。为此,我加载了两个亮度不同的图像(
img1b
img1
)。我试图让计时器以不同的延迟更改图像两次,但没有成功。我还在按钮中放置了一个侦听器,并实现了
actionPerformed
,如下所示:

public void actionPerformed(ActionEvent e) {
    if(e.getSource().equals(btnImg1)) {
        logic.piscaImagen(img1, lblImg1);
        logic.piscaImagen(img1b, lblImg1);
在逻辑类中:

public void piscaImagen(ImageIcon img, JLabel lbl) {

        Timer timer = new Timer(1250, null);
        timer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt){
                if(lbl.getIcon() != img){
                    lbl.setIcon(img);
            }
        }
        });
        timer.setRepeats(false);
        timer.start();
}

但是当我运行它时,
logic.piscaImagen
中没有任何变化。任何提示?

编辑:回答不准确,
重新绘制()
无需-请参阅注释


您缺少告诉程序需要更新显示的
repaint()
调用

@Override
public void actionPerformed(ActionEvent evt) {
    if(lbl.getIcon() != img){ 
        lbl.setIcon(img);
        lbl.repaint();
    }
}
(您的
if
语句也缺少右括号,不确定这会产生什么影响/如果是打字错误)

在我看来,你要开始两个计时器了。第一个定时器启动,改变图像,第二个定时器启动,恢复图像,所以基本上你只看到第一个图像

你只需要一个计时器。每次定时器触发时,您都会更改图像。因此,计时器中的基本代码是:

if (lbl.getIcon() == img1)
    lbl.setIcon(img1b);
else
    lbl.setIcon(img1);
或者,对于更灵活的解决方案,您可以使用


动画图标将允许您指定要显示的图标列表。然后,当计时器触发时,将显示列表中的下一个图标。您可以设置
动画图标
以进行连续显示,也可以控制循环次数。

要更快获得更好的帮助,请发布或.BTW-我建议分阶段执行。1) 在框架中的两个标签中显示这两个图像。2) 在GUI初始化期间建立一个重复计时器,以更改单个标签中的图像。3) 将repeating false(长延迟)设置为false并再次检查。4) 缩短延迟,并在单击时(而不是在启动时)通过按钮操作尝试。您不需要重新绘制()。当您更改Swing组件的属性时,该组件会在自身上调用
revalidate()
repaint()
,以确保该组件已重新绘制。特别是仅当更改属性时?例如,添加/删除组件不会触发这种情况。我发誓我以前遇到过需要重新绘制的问题,但最近我主要转向了覆盖。在面板中添加/删除组件时,需要在面板上调用
revalidate()
,以调用布局管理器(否则,新添加的组件的大小将为0)。通常情况下,面板会自己重新绘制,但我总是添加
repaint()
,只是为了确保但我现在主要转向了paintComponent重写-“-如果您正在进行自定义绘制,那么您需要重新绘制,但更好的设计是在类的属性上有一个setter方法,然后setter方法调用revalidate()并重新绘制,而不是应用程序代码。谢谢您的帮助,但它仍然不起作用,我看不到图像在变化。使用更多代码编辑=/edit:现在我看到logic.piscaImagen(img1,lblImg1)和logic.piscaImagen(img1b,lblImg1)之间的快速变化。piscaImagen(img1b,lblImg1)就像一个闪光灯,但我需要它变慢。作为一个附带问题,我已经快速查看了您的动画图标-以其他方式设置动画是否有任何真正的缺点(即,
Runnable
类每X毫秒翻转一次)?当然,假设是GUI驱动的应用程序,而不是复杂的2D渲染场景。确切地说,我想要的是更改图像,然后在一定延迟(2000ms)后恢复它,在纸上是一项简单的任务,但我不能使它工作。@Gorbles,Swing组件的更新应该在事件调度线程(EDT)上完成。有关详细信息,请阅读本教程。Swing timer代码在EDT上执行。线程可运行时不会执行。@user311762,并且已向您提供了有关如何解决问题的建议。您需要创建一个来演示您的问题。这就是创建一个带有JLabel和Swing timer的框架。它应该需要大约20行代码。代码可能是我会工作的,但如果没有,那么你可以在论坛上发布简单的代码。根据提供的信息,我们无法猜测你做错了什么。啊,我理解@camickr的这些限制。我的例子中的实现确保了组件不会跨线程访问(创建后的对象将继续运行
paintComponent
循环,直到帧被终止),但在修改代码时,我一定会记住这一点。脱轨完成!
if (lbl.getIcon() == img1)
    lbl.setIcon(img1b);
else
    lbl.setIcon(img1);