Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.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 Swing-闪烁图标未显示_Java_Swing_Timer_Icons_Glasspane - Fatal编程技术网

Java Swing-闪烁图标未显示

Java Swing-闪烁图标未显示,java,swing,timer,icons,glasspane,Java,Swing,Timer,Icons,Glasspane,我正在尝试使用玻璃窗格向用户闪烁图标。我正在运行一个javax.swing.Timer,它基本上执行以下操作: for (int i = 0; i < 3; i++) { frame.getGlassPane().setVisible(true); try { Thread.sleep(500); } catch (InterruptedException e1) { //To change body of catch statemen

我正在尝试使用玻璃窗格向用户闪烁图标。我正在运行一个
javax.swing.Timer
,它基本上执行以下操作:

for (int i = 0; i < 3; i++) {
    frame.getGlassPane().setVisible(true);
    try {
        Thread.sleep(500);
    } catch (InterruptedException e1) {
       //To change body of catch statement use File | Settings | File Templates.
        e1.printStackTrace();
    }
    frame.getGlassPane().setVisible(false);
}
for(int i=0;i<3;i++){
frame.getGlassPane().setVisible(true);
试一试{
睡眠(500);
}捕捉(中断异常e1){
//要更改catch语句的主体,请使用文件|设置|文件模板。
e1.printStackTrace();
}
frame.getGlassPane().setVisible(false);
}

不幸的是,如果我睡眠EDT(计时器中的当前线程),图标不会显示,就像
paintComponent
方法在线程进入睡眠之前没有完全调用一样。因此,当下一条指令生效时,玻璃窗格被隐藏,因此,图标永远不会显示。有没有一种方法可以使用这种(类似的)方法实现我想要的?

这应该很明显-使用单独的线程并在那里执行“闪烁逻辑”,但在EDT中修改UI。下面是一个简单的例子(应该足以理解这个想法):

publicstaticvoidmain(字符串[]args)
{
JFrame=newjframe();
最终JLabel标签=新JLabel(“X”);
label.setboorder(BorderFactory.createEmptyBorder(90,90,90,90));
frame.add(标签);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
新线程(新可运行()
{
公开作废运行()
{
对于(int i=0;i<15;i++)
{
尝试
{
setVisible(假);
睡眠(500);
setVisible(真);
睡眠(500);
}
捕捉(中断异常e1)
{
//
}
}
}
私有void setVisible(最终布尔值可见)
{
SwingUtilities.invokeLater(新的可运行()
{
公开作废运行()
{
label.setVisible(可见);
}
} );
}
}).start();
}

您可以使用
javax.swing.Timer

public FlashTimer() {

    javax.swing.Timer flashTimer = new javax.swing.Timer(500, new FlashHandler());
    flashTimer.setCoalesce(true);
    flashTimer.setRepeats(true);
    flashTimer.setInitialDelay(0);

}

public class FlashHandler implements ActionListener {

    private int counter;

    @Override
    public void actionPerformed(ActionEvent ae) {

        countrol.setVisible(counter % 2 == 0);
        counter++;
        if (counter > 3) {

            ((Timer)ae.getSource()).stop();

        }

    }

}

您可以使用javax.swing简单地完成这个过程。Timer@MadProgrammer我不能(在使用睡眠语句的情况下)因为计时器动作体是在EDT中执行的。这就是我使用独立线程的原因。虽然使用定时器w/o sleep语句很容易实现,但您只需要使用每个定时器事件反转组件可见性。无论如何,这两种方法都是可能的,而且都是正确的……你不需要使用计时器进行睡眠,让计时器负责睡眠,只需响应ActionEvent。这有点迂回,但它似乎是正确同步的
javax.swing.Timer
隐藏了复杂性。@这正是我所说的:)注意-您需要在运行之间重置
计数器;)更多的例子和例子。
public FlashTimer() {

    javax.swing.Timer flashTimer = new javax.swing.Timer(500, new FlashHandler());
    flashTimer.setCoalesce(true);
    flashTimer.setRepeats(true);
    flashTimer.setInitialDelay(0);

}

public class FlashHandler implements ActionListener {

    private int counter;

    @Override
    public void actionPerformed(ActionEvent ae) {

        countrol.setVisible(counter % 2 == 0);
        counter++;
        if (counter > 3) {

            ((Timer)ae.getSource()).stop();

        }

    }

}