我正在尝试使用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 statement use File | Settings | File Templates.
e1.printStackTrace();
}
frame.getGlassPane().setVisible(false);
}
不幸的是,如果我使EDT(计时器中的当前线程)休眠,则图标不会显示,因为在paintComponent
方法中,在线程进入睡眠状态之前无法完全调用。因此,当下一条指令启动时,玻璃窗格将被隐藏,因此,图标永远不会显示。有没有办法使用这种(类似)方法实现我想要的?
您可以使用
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();
}
}
}
这应该是显而易见的 - 使用单独的线程并在那里执行"闪烁逻辑",但在 EDT 中修改 UI。这里有一个简单的例子(应该足以理解这个想法):
public static void main ( String[] args )
{
JFrame frame = new JFrame ();
final JLabel label = new JLabel ( "X" );
label.setBorder ( BorderFactory.createEmptyBorder ( 90, 90, 90, 90 ) );
frame.add ( label );
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.pack ();
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
new Thread ( new Runnable ()
{
public void run ()
{
for ( int i = 0; i < 15; i++ )
{
try
{
setVisible ( false );
Thread.sleep ( 500 );
setVisible ( true );
Thread.sleep ( 500 );
}
catch ( InterruptedException e1 )
{
//
}
}
}
private void setVisible ( final boolean visible )
{
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
label.setVisible ( visible );
}
} );
}
} ).start ();
}