2

我正在尝试使用 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方法在线程进入休眠状态之前无法完全调用。因此,当下一条指令启动时,玻璃窗格被隐藏,因此图标永远不会显示。有没有办法使用这种(类似的)方法来实现我想要的?

4

2 回答 2

5

你可以使用一个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();

        }

    }

}
于 2012-08-15T10:09:41.663 回答
3

应该很明显 - 使用单独的线程并在那里执行“闪烁逻辑”,但在 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 ();
}
于 2012-08-15T09:30:32.593 回答