14 Replies Latest reply: Sep 12, 2008 7:40 PM by 843785 RSS

    Thread.sleep() in for loop

    843785
      Hi

      I want to pause for a defined period of time per iteration of my for loop. I've tried using Thread.sleep(time) however this seems to just pause for a second and then do my entire loop, what gives?
        @Action  public void CycleElectrodeButtonPressed() throws InterruptedException {
      
      
      for (int i = 0; i < 8; i++) 
      
           {
      
       cbarray.setSelected(true);
      Thread.sleep(1000);

      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        • 1. Re: Thread.sleep() in for loop
          843785
          You loop will sleep 1 second each iteration. Add an System.out.println("TEST"); to the for loop, and you will see a second's delay between the outputs.
          • 2. Re: Thread.sleep() in for loop
            843785
            Ah yes the loop is pausing, however the cbarray; (An array of checkboxes in my GUI) is not repainting itself (to show it has been checked) between each iteration!

            I have tried using


            cbarray.repaint()
            
            But no luck.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
            • 3. Re: Thread.sleep() in for loop
              794066
              It's a little more complicated than that. You want to run your GUI modifications on the Swing thread and make sure your timing thread doesn't block.

              This probably isn't the best way to do it (I imagine a javax.swing.Timer would be), but here's the idea:
              new Thread() {
                  public void run() {
                      for (...) {
                         long startTime = System.currentTimeMillis();
                         long currentTime = startTime;
                         while (currentTime < startTime + 1000) {
                             this.sleep(10);
                             this.yield();
                         }
                         SwingUtilities.invokeLater(new Runnable() {
                             public void run() {
                                 cbarray.setSelected(true);
              }
              });
              }
              }.start();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
              • 4. Re: Thread.sleep() in for loop
                843785
                I'm sorry I don't understand that at all or know where to put it to get it to work.

                Isn't there a simple way of getting the loop to pause and then my selection to redraw? It was two lines of code in C++, is this something to do with the Java Virtual machine not knowing the time?

                I'm a noob, please bear with me.
                • 5. Re: Thread.sleep() in for loop
                  794066
                  No. Thread.sleep() pauses the currently executing thread. What it doesn't do is give up priority to other threads. All Swing GUI updates happen on a single thread. So what you're doing is looping through, updating the GUI, and sleeping all in the same thread. All your GUI updates happen, but your thread doesn't yield to other threads, so you block the Swing thread from making your updates.

                  Without yielding, your Thread is running to completion and the Swing thread has to wait until you're done before it can render the updates to your GUI.

                  My solution yields thread priority to other threads while waiting for 1000ms to elapse. It also executes GUI updates on the Swing thread as all GUI updates should be done.
                  • 6. Re: Thread.sleep() in for loop
                    796447
                    mbishop78 wrote:
                    No. Thread.sleep() pauses the currently executing thread. What it doesn't do is give up priority to other threads. All Swing GUI updates happen on a single thread. So what you're doing is looping through, updating the GUI, and sleeping all in the same thread. All your GUI updates happen, but your thread doesn't yield to other threads, so you block the Swing thread from making your updates.
                    I'm sure you meant to clarify, but for the benefit of the OP:
                    It has nothing to do with yielding to other threads. The problem is that the sleeping is done in THE VERY THREAD (the Swing thread as mbishop78 referred to it) which is the one responsible for painting. That thread can't do two things at once (repaint while executing that method).
                    • 7. Re: Thread.sleep() in for loop
                      843785
                      I've tried adding your code into the original function and including the loop parameters but it throws up loads of errors and I don't know where to start.

                      Can you create a new thread inside a function? Don't I have to give the new thread a variable name? Does the method extend Thread?
                      • 8. Re: Thread.sleep() in for loop
                        843785
                        Read about Swing timers: [http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html]

                        In future, post Swing questions in the [Swing forum|http://forums.sun.com/forum.jspa?forumID=57]
                        • 9. Re: Thread.sleep() in for loop
                          843785
                          Thanks I didn't know it was a swing question to begin with as the C++ code I'm porting does it in two lines with no problems. But once I found that out I have cross posted. However after reading about timers and threads I am still none the wiser as to how to implement it. All I want to do is pause of an exact amount of time in a loop, I wouldnt' have thought it would be this difficult.
                          • 10. Re: Thread.sleep() in for loop
                            843785
                            Use a swing timer as has been recommended above. There's an excellent tutorial on this at the Sun tutorial site.
                            • 11. Re: Thread.sleep() in for loop
                              843785
                              It's not hard. Here is some Friday fun:
                              import java.awt.*;
                              import java.awt.event.*;
                              import javax.swing.*;
                              
                              public class Ripple {
                                  private JCheckBox[] boxes;
                                  private JButton go;
                                  private ActionListener startAnimation = new  ActionListener() {
                                      public void actionPerformed(ActionEvent evt) {
                                          go.setEnabled(false);
                                          timer.start();
                                      }
                                  };
                                  private ActionListener timerAction = new  ActionListener() {
                                      int step;
                              
                                      public void actionPerformed(ActionEvent evt) {
                                          boxes[step].setSelected(!boxes[step].isSelected());
                                          ++step;
                                          if (step >= boxes.length) {
                                              step = 0;
                                              timer.stop();
                                              go.setEnabled(true);
                                          }
                                      }
                                  };
                                  private Timer timer = new Timer(1000, timerAction);
                              
                                  public static void main(String[] args) {
                                      EventQueue.invokeLater(new Runnable(){
                                          public void run() {
                                              new Ripple().launch();
                                          }
                                      });
                                  }
                              
                                  void launch() {
                                      boxes = new JCheckBox[5];
                              
                                      JPanel cp = new JPanel(new GridLayout(0,1));
                                      for(int i=0; i<boxes.length; ++i) {
                                          boxes[i] = new JCheckBox("selection # " + (i+1));
                                          cp.add(boxes);
                              }
                              go = new JButton("Go");
                              go.addActionListener(startAnimation);
                              cp.add(go);

                              JFrame f = new JFrame("Ripple");
                              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                              f.setContentPane(cp);
                              f.pack();
                              f.setLocationRelativeTo(null);
                              f.setVisible(true);
                              }
                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                              • 12. Re: Thread.sleep() in for loop
                                843785
                                I'm trying too but I'm not sure what an actionlistener is, I've created a timer and put in a delay and I guess I want it to call a function 8 times after a dynamically allocated (by a slider) time delay so that it can iterate the array and more down the selection boxes. But I can't seem to get it to do it.
                                • 13. Re: Thread.sleep() in for loop
                                  843785
                                  eenzc wrote:
                                  I'm trying too but I'm not sure what an actionlistener is
                                  You gotta learn to walk before you learn to run. ActionListeners are more basic than timers. Learn about ActionListeners first: [http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html]
                                  • 14. Re: Thread.sleep() in for loop
                                    843785
                                    Have you gone through the Sun Swing tutorials yet? If not, you should do so. They'll help you to no end.