1

I am trying to make a simple JButton, which when being clicked causes a simple JLabel to change its text to "second text", after that I want the current thread to sleep for few seconds and finally the JLabel to change its text again, this time to a "third text". I think I have it done here, but it doesn't work the way I want it. The code provided below makes the JButton freeze for the specified timeframe, as if it is held down, and then the label changes to the its third state. Said in other words, the "seconds text" does not appear.

Please advise me how should it be done.

Thank you.

package testPackage;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Demo {

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame();
        JButton button = new JButton("Click me!");
        final JLabel label = new JLabel("first text");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        JPanel panel = new JPanel();
        panel.add(button);
        panel.add(label);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                label.setText("second text");
                try {
                    Thread.currentThread();
                    Thread.sleep(4000);
                } catch (InterruptedException exc) {
                    System.out.println("Erorrrrr");
                }

            }
        });

        frame.add(panel);
        frame.setVisible(true);
    }

}
user1990198
  • 169
  • 1
  • 3
  • 13
  • 1
    This one of the most frequently-asked questions here. You are making the Event-Dispatch Thread sleep, freezing the GUI. You must instead schedule a delayed event with `javax.swing.Timer`. – Marko Topolnik Mar 05 '13 at 13:50
  • 3
    As an aside, what do you expect the statement `Thread.currentThread();` to achieve? – Jon Skeet Mar 05 '13 at 13:51
  • Where is the third text? – 11684 Mar 05 '13 at 13:52
  • 1
    possible duplicate of [Calling sleep on current thread stalls my main GUI](http://stackoverflow.com/questions/2025186/calling-sleep-on-current-thread-stalls-my-main-gui) – Marko Topolnik Mar 05 '13 at 13:53

4 Answers4

2

The change of text property is not the only thing that has to be done to see the result when you consider the internals of Java. The control also has to be redrawn (possibly invalidated).

By calling sleep you actually stop java GUI internal worker from redrawing the control you changed. It can happen only after the sleep has finished.

Dariusz
  • 21,561
  • 9
  • 74
  • 114
0

Your GUI runs on a thread. When you sleep that thread for x number of seconds, your GUI freezes for x number of seconds.

As noted in the comments by Marko, "you must instead schedule a delayed event with javax.swing.Timer"

Steve's a D
  • 3,801
  • 10
  • 39
  • 60
0

If you sleep on the Event Dispatch Thread (the thread that handles GUI events), then the GUI will freeze. You could start a background thread from the action listener and to the sleeping there.

public void actionPerformed(ActionEvent e)
{
    label.setText("text 1");
    new Thread(new Runnable()
    {
        public void run()
        {
            try {
                Thread.sleep(1000);
            }catch (InterruptedException ignore){}

            // queue Swing code for execution on the EDT
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    label.setText("text2");
                }
            });
        }
    }).start();
}
Jesse
  • 3,751
  • 1
  • 21
  • 19
0

In the action performed method you need to release the main GUI Thread for the changes to occur:

So if you open a new Thread in the actionPerformed method it will release the main GUI thread then after the sleep call the label.setText("third text") this will change the label to second text first wait for 4secs and then change it to third text

       @Override
        public void actionPerformed(ActionEvent e) {
            label.setText("second text");
            new Thread(){
              public void run(){
                try {
                  //Thread.currentThread();
                  Thread.sleep(4000);
                  label.setText("third text");
               } catch (InterruptedException exc) {
                System.out.println("Erorrrrr");
             }
           }
         }.start();

        }
user_CC
  • 4,686
  • 3
  • 20
  • 15