3

I want to implement a feature where user need to give a input in fixed time limit. I have gone through this answer.

Time limit for an input

This example works one time. When user not giving input in fixed, programe is terminating. But i'm trying to use it multiple time in a loop. I need to check each time what user giving input. See my InputTimer Class, modified from that post answer.

InputTimer.java

public class InputTimer {
    private String str = "";
    public String responseString = "";
    private BufferedReader in;
    TimerTask task = new TimerTask() {
        public void run() {
            if (str.equals("")) {
                responseString = "";
            }
        }
    };

    public void getInput() throws Exception {
        Timer timer = new Timer();
        timer.schedule(task, 5 * 1000);

        in = new BufferedReader(new InputStreamReader(System.in));
        str = in.readLine();
        timer.cancel();
        responseString = str;
    }
}

I've tried to implement this to another class inside a loop:

for(int i=0; i<5; i++){
    System.out.println("Enter res in 5 sec: ");
    InputTimer inputTimer = new InputTimer();
    try {
        inputTimer.getInput();
    } catch (Exception e) {
        e.printStackTrace();
    }
    String responseString = inputTimer.responseString;
    if(responseString.equals("res")){
        //User typed res
    } else {
        //
    }
}

Problem: According to my logic, if user type res in 5 sec, then responseString value will be res, otherwise it'll be empty value. Here after 5 sec Still waiting for user input.

My requirement: If user type res in 5 sec, Then it will work for //User typed res tasks and go for next iterate. If user type nothing in 5 sec, user cant enter input(user input option will be gone), responseString value will become empty then, else block will execute and then go for next iteraton again.

Please help me to find out this scenario solution.

Here is an another try with Joe C solution. It's working for one time. Check the code:

public class test {
    private static BlockingQueue<String> lines = new LinkedBlockingQueue<>();
    public static String inputTimer() throws InterruptedException {

        return lines.poll(5, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            String tmp = "";
            try {
                System.out.print("Iteration " + i + ": Enter any in 5 sec: ");
                Thread t = new Thread(() -> {
                Scanner s = new Scanner(System.in);
                while (true) {
                    lines.add(s.nextLine());
                }
            });
            t.setDaemon(true); 
            t.start();
                tmp = inputTimer();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("You entered: " + tmp);
        }
    }
}

Output Log:

Iteration 0: Enter any in 5 sec: xx
You entered: xx
Iteration 1: Enter any in 5 sec: xx
You entered: null
Iteration 2: Enter any in 5 sec: xx
You entered: null
Iteration 3: Enter any in 5 sec: xx
You entered: xx
Iteration 4: Enter any in 5 sec: You entered: xx
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42

1 Answers1

1

This can be achieved with an event based model. You will need two threads for this (one of these can be the main thread).

The first thread will accept input from a Scanner and add it to an event queue (in our case, an "event" is simply the string that gets entered):

private BlockingQueue<String> lines = new LinkedBlockingQueue<>();

Start said thread in your main method:

Thread t = new Thread(() -> {
    Scanner s = new Scanner(System.in);
    while (true) {
        lines.add(s.nextLine());
    }
});
t.setDaemon(true); // so that this thread doesn't hang at the end of your program
t.start();

Then, when you want to get the input, you can get it from the queue with a timeout:

return lines.poll(5, TimeUnit.SECONDS);
Joe C
  • 15,324
  • 8
  • 38
  • 50
  • I have no idea about event queue. Where i'll add these code, and how it working. It seems diffrent than my code. – Nashid Kamal Jitu Nov 03 '18 at 19:54
  • How this work for -> 1. If user give input, take that input, `responseString = input`, go for next iteration, 2. If user dont give input, stop taking input, `responseString = ""`, go to next iteration – Nashid Kamal Jitu Nov 03 '18 at 20:01
  • The `poll` method will return the first thing that's in the queue (i.e. the first thing that the scanner thread added to it), or `null` if there is nothing there within five seconds. – Joe C Nov 03 '18 at 20:03
  • Sorry, But its not working on second iteration. In first iteration, if i type res as input, its working perfectly, if i dont type, going to second iteration. If i type res on second iteraton, its not working, always returning null. Help me fix it. thanks – Nashid Kamal Jitu Nov 03 '18 at 20:37
  • Second iteration not taking input, always returning null. Fix it please. – Nashid Kamal Jitu Nov 03 '18 at 21:04
  • Works fine for me. I trust you're not calling `close` anywhere? – Joe C Nov 03 '18 at 21:17
  • Yes, I'm Updating my question with your solution. Check it after few mins.. Thanks :) – Nashid Kamal Jitu Nov 03 '18 at 21:19
  • I also trust you are only setting up one queue and one thread (in total, not per input)? – Joe C Nov 03 '18 at 21:20
  • The only thing in your `inputTimer()` method should be your call to `poll`. Your queue needs to be at the class level, and the rest needs to be in `main` (or as a static initializer). – Joe C Nov 03 '18 at 21:29
  • i moved that to class level, Still everytime not working. Please check the updated output log. And everytime diffrent output coming. First time when i press enter, printing that value, but second time after hitting enter, it waiting, then printing null – Nashid Kamal Jitu Nov 03 '18 at 21:39
  • Re-read that my comment carefully. You acted on half of it, but not on the other half. – Joe C Nov 03 '18 at 21:52
  • I hope everything modified as you said now. But still i'm not getting expected output :( – Nashid Kamal Jitu Nov 03 '18 at 22:00
  • You should only be creating the thread once. You are creating it five times. – Joe C Nov 03 '18 at 22:04