Carácter único de entrada de la consola en java/clojure
-
13-09-2020 - |
Pregunta
¿Cómo puedo leer un solo personaje/tecla de la consola sin tener que pulsar Intro?Hay un edad de entrada en el Sol, en la base de datos de errores alegando que no se puede hacer en java puro.He encontrado estos enfoques
- JNI
- JLine [http://jline.sourceforge.net/]
- Javacurses [http://sourceforge.net/projects/javacurses/]
Me gustaría esperar a añadir una sola magic-readkey.jar
a mi classpath, y para escribir un par de líneas de código, como (def just-hit (com.acme.MagicConsole/read-char))
.
Solución
He aquí un "eco inmediato" de la aplicación utilizando JLine que se va a imprimir int
s correspondiente a la registrada pulsaciones de teclas, estructurada como una Leiningen proyecto:
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)))))
La funcionalidad en cuestión es proporcionada por el jline.Terminal
clase, que proporciona un método estático getTerminal
devolver una instancia de una plataforma específica de la subclase a la que se puede utilizar para interactuar con el terminal.Ver el Javadoc para obtener más detalles.
Vamos a ver lo que asdf
se parece a...
$ java -jar con-1.0.0-SNAPSHOT-standalone.jar
97
115
100
102
(C-c todavía mata a la aplicación, por supuesto).
Otros consejos
Para cualquier persona que pueda estar leyendo esto en el 2015 y más allá, tenga en cuenta que las versiones más recientes de JLine ya no tiene el método Terminal/getTerminal
.Estoy seguro que no hay otro (posiblemente el mejor) manera de hacer esto ahora con JLine2, pero siempre puedes usar jline "0.9.94"
y la respuesta seguirá siendo el trabajo, al menos hasta Clojure 1.6 (de la nota, ya no necesita requerir clojure.contrib
).
Como una alternativa, yo recomiendo el excelente clojure-lanterna, que es un Clojure contenedor Java Lanterna biblioteca.Como se puede ver en el docs, hay get-key
y get-key-blocking
funciones para la lectura de caracteres de entrada.
Si desea utilizar jline2 hay un ConsoleReader
clase disponible, lo que hace casi lo mismo Michał Marczyk explicado anteriormente:
(ns con.core
(:import jline.console.ConsoleReader)
(:gen-class))
(defn -main [& args]
(while true (->> (ConsoleReader.) (.readCharacter) (println))))