java/clojure 中的单字符控制台输入

发布于 2024-09-08 21:00:06 字数 431 浏览 6 评论 0原文

如何从控制台读取单个字符/键而无需按 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))

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

  • JNI
  • JLine [http://jline.sourceforge.net/]
  • Javacurses [http://sourceforge.net/projects/javacurses/]

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鲜肉鲜肉永远不皱 2024-09-15 21:00:06

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

  1. project.clj

    (defproject con“1.0.0-SNAPSHOT”
      :描述“FIXME:写入”
      :主要con.core
      :依赖关系 [[org.clojure/clojure "1.1.0"]
                     [org.clojure/clojure-contrib“1.1.0”]
                     [j行“0.9.94”]])
    
  2. src/con/core.clj

    <前><代码>(ns con.core
    (:导入jline.终端)
    (:gen 级))

    (defn -main [& args]
    (让[term(终端/getTerminal)]
    (虽然是真的
    (println(.readCharacter term System/in)))))

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

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

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

(当然,Cc 仍然会杀死应用程序。)

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

只想待在家 2024-09-15 21:00:06

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

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

For anyone who may be reading this in 2015 and beyond, note that more recent versions of JLine no longer have the method Terminal/getTerminal. I'm sure there is another (possibly better) way to do this now with JLine2, but you can always just use jline "0.9.94" and the accepted answer will still work, at least up to Clojure 1.6 (of note, you no longer need to require clojure.contrib).

As an alternative, I would recommend the excellent clojure-lanterna, which is a Clojure wrapper around the Java Lanterna library. As you can see in the docs, there are get-key and get-key-blocking functions for reading in single characters of input.

心凉怎暖 2024-09-15 21:00:06

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

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


(defn -main [& args]
  (while true (->> (ConsoleReader.) (.readCharacter) (println))))

If you want to use jline2 there is a ConsoleReader class available which does pretty much the same thing Michał Marczyk explained above:

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


(defn -main [& args]
  (while true (->> (ConsoleReader.) (.readCharacter) (println))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文