¿Cómo leer un solo carácter de la consola en Java (como lo escribe el usuario)?

¿Hay alguna manera fácil de leer un solo carácter desde la consola cuando el usuario lo está escribiendo en Java? ¿Es posible? Intenté con estos métodos, pero todos esperan que el usuario presione la tecla Entrar :

char tmp = (char) System.in.read(); char tmp = (char) new InputStreamReader(System.in).read (); char tmp = (char) System.console().reader().read(); // Java 6 

Estoy empezando a pensar que System.in no tiene conocimiento de la entrada del usuario hasta que se presione enter .

Lo que quiere hacer es poner la consola en el modo “crudo” (no se requiere edición de línea) y no “cocido” (la edición de línea requiere la tecla Intro). En los sistemas UNIX, el comando ‘stty’ puede cambiar modos

Ahora, con respecto a Java … vea la entrada de la consola Non blocking en Python y Java . Extracto:

Si su progtwig debe estar basado en la consola, debe cambiar su modo de terminal fuera de línea al modo de caracteres, y recuerde restaurarlo antes de que se cierre su progtwig. No hay una forma portátil de hacerlo a través de los sistemas operativos.

Una de las sugerencias es usar JNI. De nuevo, eso no es muy portátil. Otra sugerencia al final del hilo, y en común con la publicación anterior, es utilizar jCurses .

Necesitas golpear tu consola en modo raw. No hay una forma incorporada de plataforma independiente para llegar allí. jCurses podría ser interesante, sin embargo.

En un sistema Unix, esto podría funcionar:

  String[] cmd = {"/bin/sh", "-c", "stty raw  

Por ejemplo, si desea tener en cuenta el tiempo transcurrido entre pulsaciones de teclas, aquí hay un código de muestra para llegar allí.

No hay una forma portátil de leer los caracteres sin procesar desde una consola Java.

Algunas soluciones temporales dependientes de la plataforma se han presentado anteriormente. Pero para ser realmente portátil, tendría que abandonar el modo de consola y usar un modo de ventana, por ejemplo, AWT o Swing.

Escribí una clase de Java RawConsoleInput que usa JNA para llamar a las funciones del sistema operativo de Windows y Unix / Linux.

  • En Windows, usa _kbhit() y _getwch() de msvcrt.dll.
  • En Unix, utiliza tcsetattr() para cambiar la consola a modo no canónico, System.in.available() para verificar si los datos están disponibles y System.in.read() para leer los bytes de la consola. Un CharsetDecoder se usa para convertir bytes a caracteres.

Es compatible con la entrada sin locking y la mezcla de modo sin formato y entrada de modo de línea normal.

Use jline3 :

Ejemplo:

 Terminal terminal = TerminalBuilder.builder() .jna(true) .system(true) .build(); // raw mode means we get keypresses rather than line buffered input terminal.enterRawMode(); reader = terminal .reader(); ... int read = reader.read(); .... reader.close(); terminal.close();