-1

So I was digging around in some old java projects that I never finished and I pulled out this little number that is of my best projects ever built.

enter image description here

It's a desktop clock widget coded in java and it works perfectly fine except for one thing. The way I have it check the current time to stay updated is in a loop and the loop "crashes" in a matter of seconds so the widget no longer gets the current time.

This is how the loop is constructed (reduced in size):

public class getCurrentTime {
    public static void getTime() throws InterruptedException {
        int hour = global.calendar.get(Calendar.HOUR);
        int minute = global.calendar2.get(Calendar.MINUTE);

        if(hour == 0) {
            global.hour.setIcon(new ImageIcon("resources/hours/12.png"));
        }else if(hour == 23) {
            global.hour.setIcon(new ImageIcon("resources/hours/11.png"));
        }else {
            global.hour.setText("?");
        }

        if(minute == 0) {
            global.minute.setIcon(new ImageIcon("resources/minutes/00.png"));
        }else if(minute == 59) {
            global.minute.setIcon(new ImageIcon("resources/minutes/59.png"));
        }else {
            global.minute.setText("?");
        }
        Thread.sleep(1000);
        getTime();
    }
}

global is a class where I keep most of my variables (I know it's weird, this was like 3 years ago, it's how I used to write my programs).

So my main question is, is there a way that I can prevent the loop from "crashing"?

Thanks in advance!

galath
  • 5,717
  • 10
  • 29
  • 41
xR34P3Rx
  • 395
  • 9
  • 28
  • 5
    A loop doesn't crash. It might throw an exception. In which case, reading the exception message and stack trace would tell you, and us, what and where the problem is. Much better than guessing. – JB Nizet Jul 11 '15 at 06:22
  • 2
    please post the full exception – Karthik Jul 11 '15 at 06:42
  • I'll have to post it tomorrow, going to bed. – xR34P3Rx Jul 11 '15 at 06:45
  • 1
    Except for the obvious unlimited recursion which is addressed in an answer already, this is hardly solvable until you manage to post the exception you get, or define "crashing" more precisely. – hiergiltdiestfu Jul 11 '15 at 06:55

4 Answers4

3

This is not a loop, really. It is a recursive call. In each recursion, some more memory will be allocated, so it will after some time go out of memory. I wonder why this is a matter of seconds here, but anyway. Try using a Timer to schedule the gui update.

Edit : you are creating a new ImageIcon in each recursion. They can be rather large in memory. Maybe they are the reason for the rapid "crash".

Apart from that I suggest sticking to java naming conventions. Class names should start with a capital letter.

Fildor
  • 14,510
  • 4
  • 35
  • 67
  • 1
    If it's not a loop, it's strictly speaking not about "iterations", but "recursions" ;) – hiergiltdiestfu Jul 11 '15 at 06:58
  • Absolutely. Fixed that @hiergiltdiestfu – Fildor Jul 11 '15 at 07:01
  • Fildor, I guess the word you're looking for is `StackOverflowException`, because this is an infinite recursion. – Tom Jul 11 '15 at 07:23
  • 1
    @Tom we can only speculate that this is the exception being thrown. But as the op did not specify "crash" it could as well be something else we cannot see from the given code. – Fildor Jul 11 '15 at 07:26
2

Thread.sleep(1000); is not going to be a good option. You can use Timer. By using a Timer you schedule a task at regular intervals.

  Timer timer = new Timer();
  long interval = (1000) ; // 1 sec

  timer.schedule( new TimerTask() {
       public void run() {
          //do your work;
       }
  }, 0, interval); 

If you want to stop the scheduling, you can use timer.cancel();

EDIT: as Fildor said I think memory is your problem. Use timer this way, it should solve your problem.

Karthik
  • 4,950
  • 6
  • 35
  • 65
  • i just got a chance to implement this solution. SO far its going great and im just going to fix another small issue with the images overlapping. Thanks! Ill update my solution later tonight. – xR34P3Rx Jul 12 '15 at 23:49
0

This is first solution

class clockUpdater implements Runnable {

   @Override
   public void run() {
      Thread.sleep(WAIT_TILL_NEW_MINUTE);
      while(true){ //a infinite loop    
      // the Swing call below must be queued onto the Swing event thread
      SwingUtilities.invokeLater(new Runnable(){
         @Override
         public void run() {            
            //your clock updating code here
         }
      });
      try {
         Thread.sleep(1000*60);//you only need to update once after a minute
      } catch (InterruptedException e) {
        // ....
      }
     }
   }
}

This is second

class clockUpdater extends Thread{
  @Override

      public void run(){
         Thread.sleep(WAIT_TILL_NEW_MINUTE);
         while(true){
         try{
             //your update code here
             Thread.sleep(60*1000)//
             }
          catch(Exception e){
              //..
           }
         }
       }
     }

Note: You need to start this as soon as the minute changes in system time. Or clock time will lag behind. Calculate WAIT_TILL_NEW_MINUTE as soon as your program starts. Better to update only when it is needed.

Rahul
  • 289
  • 2
  • 7
-1

The answer for your question is use set timeout function for the function which you want to avoid loop crashing. Like:

setTimeout(function()  {
    // write the logic
},1000);
Tom
  • 16,842
  • 17
  • 45
  • 54