1

I'm a java newbie and I'm creating a scheduler program using netbeans. My software will get Time and action from the user and enter those data in to separate arraylists. I've then used javax.swing.timer to start a countdown timer. When user finished entering data and hit the "run" button,The timer will get the running time from the first element in the array list and start counting down. when the countdown time reach 0 , timer will get the count down time from the next element in the array list, and so on.

My problem is, the timer runs perfectly but when there is no more elements in the arraylist, it still won't stop. Please help me with this. Here's the part of my code I'm having trouble with:

private void btnstartRunActionPerformed(java.awt.event.ActionEvent evt) {                                            
  countdown = ActionTime.get(0);
  Action.setText(ActionName.get(c));
  timer = new Timer(1000,new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent event){

      if(countdown<=0){
          try{
            c++;
            Action.setText(ActionName.get(c));
            //this nested if statement is to check whether the array has any more elements.
            //(This is the part that doesn't work.)
            if(c >= ActionTime.size()){
              timer.stop();
              JOptionPane.showMessageDialog(null, "Workout Completed!");
            }  
            countdown=ActionTime.get(c);
            timer.restart();

          } catch (Exception error2){
          }
       }
       Time.setText(Integer.toString(countdown));
       countdown--;
     }
  });
  timer.start();
}                                           
Simulant
  • 19,190
  • 8
  • 63
  • 98
mattmorgan
  • 13
  • 2
  • 5
  • 1
    For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve). The typical way to stop a `Timer` is to call `timer.stop()`. – Andrew Thompson Jan 21 '14 at 08:40
  • this might help http://stackoverflow.com/questions/1409116/how-to-stop-the-task-scheduled-in-java-util-timer-class – Mehul Rathod Jan 21 '14 at 08:41
  • 1
    I'm surprised you don't get error with `ActionName.get(c)` `:/` – ADTC Jan 21 '14 at 08:42
  • 3
    BTW - Change code of the form `catch (Exception e) { ..` to `catch (Exception e) { e.printStackTrace(); // very informative! ..` – Andrew Thompson Jan 21 '14 at 08:42
  • 1
    @ADTC they might be getting an `Exception`, the code catches and ignores them! – Andrew Thompson Jan 21 '14 at 08:43
  • 1
    Ah yes I see it.. Wow, so many beginners make this mistake of ignoring the `Exception`... – ADTC Jan 21 '14 at 08:44
  • ADTC, ActionName is the array list. but it doesn't give me any error. – mattmorgan Jan 21 '14 at 08:50
  • @mattmorgan Have you changed the code the way I suggested yet, or is it still ***ignoring*** exceptions? – Andrew Thompson Jan 21 '14 at 08:51
  • Unless you've changed the code so you are doing something with the exception there, you have no idea whether it gives an error or not. – Radiodef Jan 21 '14 at 08:56
  • @mattmorgan please see my answer. You think it doesn't give you any error because you wrote the code in such a way that it ignores the error. – ADTC Jan 21 '14 at 08:56
  • well, the timer works perfectly until it reach the end of the Arraylist. that's my problem. how to stop it when my arrayList (named as ActionTime) has no more elements. what am I doing wrong with the if statement? – mattmorgan Jan 21 '14 at 08:57
  • Andrew Thompson, I did as you say. it throws a bunch of errors in the output screen. – mattmorgan Jan 21 '14 at 08:58
  • @mattmorgan again, please see my answer. Nothing is wrong with your `if` statement. It's the order and structure of your program that's wrong. – ADTC Jan 21 '14 at 08:58
  • 1
    As @ADTC says, your if statement is fine. The statement before it probably throws an IndexOutOfBoundsException. You just have to check the index *before* accessing the ArrayList. – Radiodef Jan 21 '14 at 09:00
  • Radiodef, how should I do that? – mattmorgan Jan 21 '14 at 09:08

2 Answers2

2

You should change:

            c++;
            Action.setText(ActionName.get(c)); //move this down
            if(c>=ActionTime.size()){
                timer.stop();
                JOptionPane.showMessageDialog(null, "Workout Completed!");
            }

to:

            c++;
            if(c>=ActionTime.size()){
                timer.stop();
                JOptionPane.showMessageDialog(null, "Workout Completed!");
                return; //add this too as the program should not continue with below
            }
            Action.setText(ActionName.get(c)); //to here

Because when you attempt to do ActionName.get(c) when the value of c exceeds the maximum possible value, the get method will throw an Exception. That leads us to the second mistake you're making:

           catch(Exception error2){

           }

Doing this makes the program ignore the Exception and continue as though nothing happened. An easy-to-make mistake that deceived you into thinking something else is wrong, but now you know! Change it to:

           catch(Exception error2){
                error2.printStackTrace();
                System.exit(-1); //or some error handling
           }

Or remove the try/catch block so that the Exception will end your program or is handled some other way.

ADTC
  • 8,999
  • 5
  • 68
  • 93
  • They could also just remove the try/catch. As far as I can see there is no reason for it. – Radiodef Jan 21 '14 at 08:50
  • @Radiodef Yes, but the poor lad is a beginner. Let's not confuse them `:)` Regardless, I have added a note. – ADTC Jan 21 '14 at 08:52
  • Well, I did as you said. I removed the try catch block and changed the code exactly as you suggested. at the end of the array it show the message box saying "Workout complete!" but yet it show a bunch of errors in the output window. – mattmorgan Jan 21 '14 at 09:06
  • 1
    Are any of the errors `OutOfBoundsException`? If not, what are they? *Errors are your friends. Don't dismiss them as "bunch of errors". Look at them and you will find them very useful to fixing the problems in your program.* – ADTC Jan 21 '14 at 09:09
  • It may be necessary to add a `return;` statement as the last statement of your `if` block, otherwise the program will continue to execute statements that appear after the `if` block. (See my new edit.) – ADTC Jan 21 '14 at 09:11
  • Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 6, Size: 6 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.get(ArrayList.java:322) at workoutmatetimer.workoutmate$11.actionPerformed(workoutmate.java:584) – mattmorgan Jan 21 '14 at 09:13
  • Please see my comments and edits. You need to add a `return;` statement as I just said. And I hope you don't look at errors like they are some alien language `:)` There are a lot of useful information there, like *"index out of bounds"* or *"the error happened at workoutmate.java's line 584"*. You can look at the error stack trace and tell all that. – ADTC Jan 21 '14 at 09:15
  • well, adding return; at the end of the if statement worked perfectly. Now there's no errors. Thanks ADTC !!!! and thanks others for help. anything else I should know? – mattmorgan Jan 21 '14 at 09:16
  • Just take note that you will do well if you learn how to read and understand errors in console, rather than dismiss them as "bunch of errors" (see previous comment).. _Would be nice if you clicked the check mark `:)`_ – ADTC Jan 21 '14 at 09:18
0

here is an example for you:

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

import javax.swing.JFrame;
import javax.swing.Timer;

public class Main extends JFrame {
    Timer timer;

    int counter;

    Main(String title) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ActionListener a = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Counter = " + counter);

                if (++counter > 10) {
                    timer.stop();
                    System.exit(0);
                }
            }
        };

        timer = new Timer(300, a);
        timer.start();

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new Main("Timer Demo1");
    }
}
SuRu
  • 739
  • 1
  • 6
  • 19