Односимвольный консольный ввод в java/clojure
-
13-09-2020 - |
Вопрос
Как я могу прочитать один символ / клавишу с консоли без необходимости нажимать Enter?Существует старая запись в базе данных Sun об ошибках утверждая, что это невозможно сделать на чистом java.Я нашел эти подходы
- ДЖНИ
- JLine [http://jline.sourceforge.net /]
- Javacurses [http://sourceforge.net/projects/javacurses /]
Я бы ожидал добавить один magic-readkey.jar
к моему пути к классу и написать несколько строк кода, например (def just-hit (com.acme.MagicConsole/read-char))
.
Решение
Вот приложение "immediate echo", использующее JLine, которое будет печатать int
s, соответствующие зарегистрированным нажатиям клавиш, структурированные в виде Лейнинген проект:
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)))))
Функциональность, о которой идет речь, обеспечивается jline.Terminal
класс, который предоставляет статический метод getTerminal
возвращает экземпляр подкласса, зависящего от платформы, который может использоваться для взаимодействия с терминалом.Увидеть Javadoc для получения более подробной информации.
Давайте посмотрим, что asdf
выглядит как...
$ java -jar con-1.0.0-SNAPSHOT-standalone.jar
97
115
100
102
(С-с конечно, приложение по-прежнему отключается.)
Другие советы
Для всех, кто, возможно, будет читать это в 2015 году и далее, обратите внимание, что в более поздних версиях JLine больше нет этого метода Terminal/getTerminal
.Я уверен, что есть другой (возможно, лучший) способ сделать это сейчас с помощью JLine2, но вы всегда можете просто использовать jline "0.9.94"
и принятый ответ все равно будет работать, по крайней мере, до Clojure 1.6 (обратите внимание, вам больше не нужно требовать clojure.contrib
).
В качестве альтернативы я бы порекомендовал отличный клоджуре-лантерна, который представляет собой оболочку Clojure вокруг Java Лантерна библиотека.Как вы можете видеть в документы, есть 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))))
.