Java Swing - Flashing icon not showing up

750 Views Asked by At

I am trying to flash the icon to the user using a GlassPane. I am running a javax.swing.Timer which basically performs this:

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

Unfortunatly, if I sleep the EDT (current thread within the timer), the icon does not show, as in the paintComponent method did not manage to get invoked fully before the thread went to sleep. Therefore, when the next instruction kicks in, the glass pane is hidden, and, as a result, the icon is never shown. Is there a way to achieve what I want using this (similiar) approach?

2

There are 2 best solutions below

1
On BEST ANSWER

You could use a 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();

        }

    }

}
6
On

It should be obvious - use a separate Thread and do the "blinking logic" there but modify the UI in EDT. Here is a simple example (should be enough to understand the idea):

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