Einzelzeichen-Konsoleneingabe in Java/Clojure
-
13-09-2020 - |
Frage
Wie kann ich ein einzelnes Zeichen/eine einzelne Taste von der Konsole lesen, ohne die Eingabetaste drücken zu müssen?Da ist ein Alter Eintrag in der Fehlerdatenbank von Sun Ich behaupte, dass dies in reinem Java nicht möglich sei.Ich habe diese Ansätze gefunden
- JNI
- JLine [http://jline.sourceforge.net/]
- Javacurses [http://sourceforge.net/projects/javacurses/]
Ich würde erwarten, eine Single hinzuzufügen magic-readkey.jar
zu meinem Klassenpfad hinzufügen und ein paar Zeilen Code schreiben (def just-hit (com.acme.MagicConsole/read-char))
.
Lösung
Hier ist eine „Sofort-Echo“-App mit JLine, die gedruckt wird int
s entsprechen registrierten Tastendrücken, strukturiert als Leiningen Projekt:
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)))))
Die betreffende Funktionalität wird von bereitgestellt jline.Terminal
Klasse, die eine statische Methode bereitstellt getTerminal
Gibt eine Instanz einer plattformspezifischen Unterklasse zurück, die zur Interaktion mit dem Terminal verwendet werden kann.Siehe die Javadoc für mehr Details.
Mal sehen, was asdf
sieht aus wie...
$ java -jar con-1.0.0-SNAPSHOT-standalone.jar
97
115
100
102
(C-c beendet die App natürlich immer noch.)
Andere Tipps
Für alle, die dies im Jahr 2015 und darüber hinaus lesen, sei darauf hingewiesen, dass neuere Versionen von JLine diese Methode nicht mehr haben Terminal/getTerminal
.Ich bin mir sicher, dass es jetzt mit JLine2 eine andere (möglicherweise bessere) Möglichkeit gibt, dies zu tun, aber Sie können es immer einfach verwenden jline "0.9.94"
und die akzeptierte Antwort funktioniert immer noch, zumindest bis Clojure 1.6 (beachten Sie, dass Sie keine Anforderung mehr benötigen clojure.contrib
).
Als Alternative würde ich das Excellent empfehlen Clojure-Laterne, ein Clojure-Wrapper um Java Lanterna Bibliothek.Wie Sie darin sehen können die Dokumente, es gibt get-key
Und get-key-blocking
Funktionen zum Einlesen einzelner Zeichen der Eingabe.
Wenn Sie Jline2 verwenden möchten, gibt es eine generakodicetagcode-Klasse, die so ziemlich dasselbe ist, was Michał Marczyk oben erklärt hat:
generasacodicetagpre.