Pergunta

Como posso ler um único caractere/chave do console sem precisar pressionar Enter?Há um entrada antiga no banco de dados de bugs da Sun alegando que isso não pode ser feito em java puro.Eu encontrei essas abordagens

Eu esperaria adicionar um único magic-readkey.jar para o meu caminho de classe e escrever algumas linhas de código, como (def just-hit (com.acme.MagicConsole/read-char)).

Foi útil?

Solução

Aqui está um aplicativo de "eco imediato" usando JLine que irá imprimir ints correspondentes a pressionamentos de tecla registrados, estruturados como um Leiningen projeto:

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

A funcionalidade em questão é fornecida pelo jline.Terminal classe, que fornece um método estático getTerminal retornando uma instância de uma subclasse específica da plataforma que pode ser usada para interagir com o terminal.Veja o Javadoc para mais detalhes.

Vamos ver o que asdf parece...

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

(C-c ainda mata o aplicativo, é claro.)

Outras dicas

Para quem estiver lendo isso em 2015 e além, observe que as versões mais recentes do JLine não possuem mais o método Terminal/getTerminal.Tenho certeza de que há outra maneira (possivelmente melhor) de fazer isso agora com JLine2, mas você pode simplesmente usar jline "0.9.94" e a resposta aceita ainda funcionará, pelo menos até o Clojure 1.6 (observe que você não precisa mais exigir clojure.contrib).

Como alternativa, recomendaria o excelente lanterna-clojure, que é um wrapper Clojure em torno do Java lanterna biblioteca.Como você pode ver em os documentos, há get-key e get-key-blocking funções para leitura em caracteres únicos de entrada.

Se você quiser usar o jline2, existe um ConsoleReader classe disponível que faz praticamente a mesma coisa que Michał Marczyk explicou acima:

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


(defn -main [& args]
  (while true (->> (ConsoleReader.) (.readCharacter) (println))))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top