0

I was having some problem with TimerTask in java. Basically what I am trying to do is for each session to compute something, I set one minute time frame, once the time is up, I will prompt users to input whether to start another session. Here is what I have tried:

    String toCont = "";
    Scanner scanner = new Scanner(System.in);
    
    do {
        long delay = TimeUnit.MINUTES.toMillis(1);
        Timer t = new Timer();
        int marks = startSession(); // function to compute some marks
        
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!");
                System.out.print("Do you wished to start a new game? (Y/N): ");
                toCont = scanner.next();
            }
        };
        t.schedule(task, delay);

    } while (toCont.equals("y") || toCont.equals("Y"));

However, I am having some syntax error on the toCont variable in run(). Error message as such "Local variable toCont defined in an enclosing scope must be final or effectively final". Any ideas how can I resolve this? Thanks!

QWERTY
  • 2,303
  • 9
  • 44
  • 85
  • Not much point in the `Timer` or the anonymous inner `TimerTask` class really. A mere `Thread.sleep(ldelay)` would accomplish the same thing without the problems. – user207421 Apr 18 '22 at 07:58

2 Answers2

1

Make the variable into a final single-element array.

final String[] toCont = {
    ""
};
Scanner scanner = new Scanner(System.in);

do {
    long delay = TimeUnit.MINUTES.toMillis(1);
    Timer t = new Timer();
    int marks = startSession(); // function to compute some marks

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            System.out.println("Time's up!");
            System.out.print("Do you wished to start a new game? (Y/N): ");
            toCont[0] = scanner.next();
        }
    };
    t.schedule(task, delay);

} while (toCont[0].equals("y") || toCont[0].equals("Y"));
stefano
  • 336
  • 2
  • 8
  • I think the approach above breaks the timer. Cause it does not prompt the times up after 1 minute – QWERTY Apr 18 '22 at 07:03
  • Did you make sure to update any other references in your code? You would need to replace all `toCont` with `toCont[0]` – stefano Apr 18 '22 at 07:04
  • I am getting this error message upon printing the prompt to start new game: Exception in thread "Timer-0" java.lang.IndexOutOfBoundsException: end – QWERTY Apr 18 '22 at 07:14
  • Do you get this same error when you aren't using the String Array? ...or is it only with using the String Array? – stefano Apr 18 '22 at 07:19
  • Hi I didn't get the error when not using the String array. But then my solution above is having syntax error. if I commented out it works fine just that it does not prompt to start a new game – QWERTY Apr 18 '22 at 07:23
  • Can you send the full stack trace? – stefano Apr 18 '22 at 07:25
  • Hi! Please see following. Do you wished to start a new game? (Y/N): Exception in thread "Timer-0" java.lang.IndexOutOfBoundsException: end at java.util.regex.Matcher.region(Matcher.java:1038) at java.util.Scanner.getCompleteTokenInBuffer(Scanner.java:907) at java.util.Scanner.next(Scanner.java:1362) at Game$1.run(Game.java:23) at java.util.TimerThread.mainLoop(Timer.java:555) at java.util.TimerThread.run(Timer.java:505) – QWERTY Apr 18 '22 at 07:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243983/discussion-between-stefano-and-qwerty). – stefano Apr 18 '22 at 07:34
  • @QWERTY Please mark my answer as correct – stefano Apr 18 '22 at 22:31
-1

To use a variable inside an inner class you must declare it final. add this in your do while loop(workaround)

do {
        long delay = TimeUnit.MINUTES.toMillis(1);
        final Integer innertoCont = new Integer(toCont);
        Timer t = new Timer();
        int marks = startSession(); // function to compute some marks
        
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Time's up!");
                System.out.print("Do you wished to start a new game? (Y/N): ");
                innertoCont = scanner.next();
            }
        };
        t.schedule(task, delay);

    } while (toCont.equals("y") || toCont.equals("Y"));
Deb Das
  • 264
  • 1
  • 7
  • I think this approach is having same syntax error as my approach above – QWERTY Apr 18 '22 at 07:25
  • Changing innertoCont from a String to an Integer doesn't help; and you can't declare a variable final and then reassign it: that is what final means. – khelwood Apr 18 '22 at 07:47