java / clojure中的单字符控制台输入
如何从控制台读取单个字符/键而无需按Enter键? Sun的bug数据库中有一个旧条目声称无法在纯java中完成。 我找到了这些方法
- JNI
- JLine [ http://jline.sourceforge.net/]
- Javacurses [ http://sourceforge.net/projects/javacurses/]
我希望在我的类路径中添加一个magic-readkey.jar
,并编写几行代码,如(def just-hit (com.acme.MagicConsole/read-char))
。
这是一个使用JLine的“立即回声”应用程序,它将打印与注册的按键相对应的int
,结构为Leiningen项目:
-
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"]])
-
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)))))
有问题的function由jline.Terminal
类提供,它提供了一个静态方法getTerminal
,它返回一个特定于平台的子类的实例,可用于与终端进行交互。 有关更多详细信息,请参阅Javadoc 。
让我们看看asdf
样子……
$ java -jar con-1.0.0-SNAPSHOT-standalone.jar 97 115 100 102
(当然, Cc仍会杀死应用程序。)
对于可能在2015年及以后阅读此内容的任何人,请注意更新版本的JLine不再具有Terminal/getTerminal
方法。 我确信现在有另一种(可能更好)的方法可以使用JLine2,但你可以随时使用jline "0.9.94"
并且接受的答案仍然可以使用,至少可以使用Clojure 1.6(注意,你不再需要clojure.contrib
)。
作为替代方案,我会推荐优秀的clojure-lanterna ,它是Java Lanterna库周围的Clojure包装器。 正如您在文档中看到的那样,有get-key
和get-key-blocking
函数用于读取输入的单个字符。
如果你想使用jline2,可以使用一个ConsoleReader
类,它与MichałMarczyk上面解释的几乎相同:
(ns con.core (:import jline.console.ConsoleReader) (:gen-class)) (defn -main [& args] (while true (->> (ConsoleReader.) (.readCharacter) (println))))