通过计时器设置JDialog的不透明度

5

我正在使用以下代码来使用javax.swing.Timer实现淡入一个JDialog

    float i = 0.0F;
    final Timer timer = new Timer(50, null);
    timer.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (i == 0.8F){
                timer.stop();
            }
            i = i + 0.1F;
            setOpacity(i);
        }
    });
    timer.start();

Dialog 被漂亮地淡入,效果也很好,但最后出现了 IllegalArgumentException 错误,错误信息如下:

 The value of opacity should be in the range [0.0f .. 1.0f]

但问题是,我并没有超出 i = 0.8F 的范围,那么它怎么会成为非法参数呢?
异常出现在这一行:setOpacity(i);

有任何建议或解决方案吗?


1
我建议您检查代码,因为您修改的“i”可能不是您期望的那个。它不能是“final float i = 0.0F;”变量,因为该变量已被声明为“final”。 - Robin
抱歉@Robin,这只是我的打字错误,这次已经编辑过了。如果我将其设为最终版本,则会引发“编译器错误”而不是“异常”。感谢您指出这一点。 :) - Asif
我可以问一下这个"setOpacity"方法是什么吗?我也在尝试实现对话框的淡入/淡出。 - Aurelien Ribon
当然可以问..setOpacity(float),这是Java SE 7中java.awt.Frame的方法,它是JFrame的超类。 - Asif
哦,我明白了,谢谢。我一直在尝试维护我所有开源应用程序的1.6兼容性,所以我从来没有见过这种方法,但我想强制使用1.7不会真正伤害用户。此外,当Java8出现时,我将首先采用lambda表达式:)谢谢。 - Aurelien Ribon
1个回答

8

你的问题在于你正在处理浮点数,并且==不能很好地与它们一起使用,因为你不能准确地描述浮点数中的0.8,所以你的计时器将永远不会停止。

使用>=。或者更好的方法是只使用整数。

例如:

int timerDelay = 50; // msec
new Timer(timerDelay, new ActionListener() {
    private int counter = 0;

    @Override
    public void actionPerformed(ActionEvent e) {
        counter++;
        if (counter == 10){
            ((Timer)e.getSource()).stop();
        }
        setOpacity(counter * 0.1F);
    }
}).start();

1
哇!太简单了,也很有用。非常感谢!还有一件事,这样做是否合法?我的意思是使用计时器和淡入对话框,我希望它不会违反标准的Swing编码规范? - Asif
我不知道与此相关的任何“标准”,也没有任何关于Swing的标准,只是有关线程方面的注意事项,我不认为这会干扰线程。 - Hovercraft Full Of Eels
是的,我的关注点在于Swing线程模型和EDT事项,我希望这不会打扰它们,因为我非常喜欢我的这个小调整 :-) - Asif
1
@mprab:但他在这里所需要的只是使用整数。 - Hovercraft Full Of Eels
@HovercraftFullOfEels 我正在使用带有>=符号的float,因为使用int只会有8个不透明度级别,在淡入效果中这有点少。 - Asif
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接