groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Merlin Beedell <>
Subject Getting console input with a timeout
Date Mon, 27 Apr 2015 09:57:32 GMT
I am trying to get Console Input when running simple scripts that stop with questions for user
input – but that a default response would be used after a short timeout.  Thus a script
could be run manually or run automatically.
  I found a handy example here from Dr.
Heinz M. Kabutz.
However, I find that the keypresses are not echoed back to the user until the Enter key is
pressed.  This is a bit of a problem. It does this for both System.Console or 
I thought that adding thread “yield” calls might help, but they do not.  I don’t know
if this is a problem only when run under Groovy.

Anyway, I have tried to groovy-ize the Java version below. But I wonder if the MetaClass
could be extended to provide the timeout functionality, rather than wrapping things on top
– and would that help?  Or perhaps to find a way to inject keypresses into the
from a separate thread, to pop the Enter keypress after the timeout?

import java.util.concurrent.*;

    ConsoleInput con = new ConsoleInput();

    String input = con.readLine("What is your name? ", "Fred", 15);

    //def input = //this does echo keystrokes

    println("Done. Your input was: " + input);

    input = con.readLine("What is your age? ", "50", 5);

    println("Done. Your input was: " + input);

public class ConsoleInput {

  private final TimeUnit unit = TimeUnit.SECONDS;

       //Console cons = System.console()

  BufferedReader br = new BufferedReader(System.console().reader());

  //This is groovies weird syntax for implementing an interface.  Each map entry is a closure
implementing a method of that name.

  // it supports the usual class implementation syntax as well, of course.

  def myReader =  [

   call: {

      String input;

      try {

        // wait until we have data to complete a readLine()

        while (!br.ready()) {





        input = br.readLine();

      } catch (InterruptedException e) {

        return null;


      return input;


  ] as Callable

  public String readLine(String sPrompt, String sDefault, int timeout) throws InterruptedException

    print "$sPrompt [$sDefault]: "

    ExecutorService ex = Executors.newSingleThreadExecutor();

    String input = null;

    //note: groovy does not support the do/while loop syntax.  Strange!

    try {

        Future<String> result = ex.submit(


        try {

          input = result.get(timeout, unit);

        } catch (ExecutionException e) {


        } catch (TimeoutException e) {


          println ""  //user input always has a newline - so we must add one after timeout


    } finally {



    return input?:sDefault;



Merlin Beedell

View raw message