如何在不按Enter键的情况下从控制台读取单个字符/键?有一个 Sun的bug数据库中的旧条目 声称它不能在纯java中完成。我发现了这些方法

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

有帮助吗?

解决方案

这是一个使用JLine的"立即回声"应用程序,它将打印 ints对应于注册的按键,结构为 莱宁根 工程项目:

  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 返回可用于与终端交互的特定于平台的子类的实例。查看 贾瓦多克 有关更多详情。

让我们看看 asdf 看起来像。..

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

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

其他提示

对于任何可能在2015年及以后阅读本文的人,请注意,JLine的最新版本不再具有该方法 Terminal/getTerminal.我确信现在有另一种(可能更好)的方法可以用JLine2做到这一点,但你总是可以只使用 jline "0.9.94" 并且接受的答案仍然有效,至少达到Clojure1.6(值得注意的是,您不再需要要求 clojure.contrib).

作为替代方案,我会推荐优秀的 clojure至兰特纳航线, ,这是围绕Java的Clojure包装器 兰特纳 图书馆。正如你在 文件, ,有 get-keyget-key-blocking 用于在输入的单个字符中读取的函数。

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

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


(defn -main [& args]
  (while true (->> (ConsoleReader.) (.readCharacter) (println))))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top