Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How could I add a simple delay in a Java Swing application?

I'd like to know how to add a time delay inside a Swing app in Java, I used Thread.sleep(time), and also I used SwingWorker but it doesn't work. Here's part of my code:

switch (state) {
    case 'A':
        if (charAux == 'A') {
            state = 'B';                    
            //Here's where I'd like to add a time delay
            jLabel13.setForeground(Color.red);
            break;
        } else {                            
            //Here's where I'd like to add a time delay
            jLabel12.setForeground(Color.red);
            break;
        }
}

I hope you could help me or solve my doubts when I'm using SwingWorker.

like image 965
Juan Reséndiz Avatar asked Dec 03 '22 01:12

Juan Reséndiz


2 Answers

Here's an example using a javax.swing.Timer

public class TestBlinkingText {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BlinkPane());
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }            
        });
    }

    protected static class BlinkPane extends JLabel {

        private JLabel label;
        private boolean state;

        public BlinkPane() {

            label = new JLabel("Look at me!");
            setLayout(new GridBagLayout());

            add(label);

            Timer timer = new Timer(500, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {                    
                    state = !state;
                    if (state) {
                        label.setForeground(Color.RED);
                    } else {
                        label.setForeground(Color.BLACK);
                    }                    
                    repaint();                    
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.setInitialDelay(0);
            timer.start();            
        }        
    }    
}
like image 100
MadProgrammer Avatar answered Dec 23 '22 12:12

MadProgrammer


Good thing you removed the Thread.sleep as that would make your UI unresponsive for those 2 seconds.

What you can do is start a Timer which only runs once:

int delay = 2000;
Timer timer = new Timer( delay, new ActionListener(){
  @Override
  public void actionPerformed( ActionEvent e ){
    jLabel12.setForeground( Color.red );
  }
} );
timer.setRepeats( false );
timer.start();

Note that the Timer is a javax.swing.Timer, which assures that the actionPerformed method of the ActionListener is called on the Event Dispatch Thread, respecting the Swing threading rules.

This is also possible with a SwingWorker, but I would stick to the Timer for this. In case you want to use the SwingWorker, you can simply use Thread.sleep in the doInBackground() method, and update the JLabel in the done() method.

Something along the lines of

class Delay extends SwingWorker<Void, Object> {
 @Override
 public void doInBackground() {
  Thread.sleep( 2000 );
 }

 @Override
 protected void done() {
   jLabel12.setForeground( Color.red );
 }
}
like image 28
Robin Avatar answered Dec 23 '22 10:12

Robin