8

如何从控制台读取单个字符/键而无需按 Enter?Sun 的错误数据库中有一个旧条目声称它不能在纯 java 中完成。我找到了这些方法

我希望magic-readkey.jar在我的类路径中添加一个,并编写几行代码,例如(def just-hit (com.acme.MagicConsole/read-char)).

4

3 回答 3

12

这是一个使用 JLine 的“立即回显”应用程序,它将打印int与注册按键相对应的 s,结构为Leiningen项目:

  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)))))
    

所讨论的功能由jline.Terminal该类提供,该类提供了一个静态方法,该方法getTerminal返回一个特定于平台的子类的实例,该子类可用于与终端交互。有关更多详细信息,请参阅Javadoc

让我们看看是什么asdf样子...

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

C-c当然,仍然会杀死应用程序。)

于 2010-07-11T23:45:27.407 回答
4

对于可能在 2015 年及以后阅读本文的任何人,请注意 JLine 的更新版本不再具有方法Terminal/getTerminal。我确信现在使用 JLine2 可以使用另一种(可能更好)方法,但您始终可以使用jline "0.9.94"并且接受的答案仍然有效,至少到 Clojure 1.6(请注意,您不再需要 require clojure.contrib) .

作为替代方案,我会推荐优秀的clojure-lanterna,它是 Java Lanterna库的 Clojure 包装器。正如您在文档中看到的那样,有用于读取单个输入字符的函数get-keyget-key-blocking

于 2015-04-09T15:18:06.520 回答
2

如果你想使用 jline2 有一个ConsoleReader可用的类,它与上面解释的 Michał Marczyk 几乎相同:

(ns con.core
  (:import jline.console.ConsoleReader)
  (:gen-class))


(defn -main [& args]
  (while true (->> (ConsoleReader.) (.readCharacter) (println))))
于 2015-11-19T18:17:17.653 回答