javaclojureuser-inputconsole.readkey

Single character console input in java/clojure


How can I read a single character/key from the console without having to hit Enter? There is an old entry in Sun's bug database claiming that it can't be done in pure java. I've found these approaches

I'd expect to add a single magic-readkey.jar to my classpath, and to write a few lines of code, like (def just-hit (com.acme.MagicConsole/read-char)).


Solution

  • Here's an "immediate echo" app using JLine which will print ints corresponding to registered keypresses, structured as a Leiningen project:

    1. project.clj:

      (defproject con "1.0.0-SNAPSHOT"
        :description "FIXME: write"
        :main con.core
        :dependencies [[org.clojure/clojure "1.1.0"]
                       [org.clojure/clojure-contrib "1.1.0"]
                       [jline "0.9.94"]])
      
    2. src/con/core.clj:

      (ns con.core
        (:import jline.Terminal)
        (:gen-class))
      
      (defn -main [& args]
        (let [term (Terminal/getTerminal)]
          (while true
            (println (.readCharacter term System/in)))))
      

    The functionality in question is provided by the jline.Terminal class, which provides a static method getTerminal returning an instance of a platform-specific subclass which can be used to interact with the terminal. See the Javadoc for more details.

    Let's see what asdf looks like...

    $ java -jar con-1.0.0-SNAPSHOT-standalone.jar 
    97
    115
    100
    102
    

    (C-c still kills the app, of course.)