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();
}
}
}