Чтение с клавиатуры без нажатия "enter" с помощью JCurses
Я пишу приложение, которое требует, чтобы я прочитал ключ с консоли, не дожидаясь, пока пользователь нажмет клавишу ввода. Я прочитал, что библиотека JCurses может помочь.
Я пытался с помощью Toolkit.readCharacter()
как это:
InputChar c = Toolkit.readCharacter();
system.out.println(c.getCharacter());
Но проблема заключалась в том, что readCharacter()
Метод не завершает выполнение независимо от того, сколько символов вы вводите. Даже если вы нажмете ввод, все равно кажется, что он ждет ввода символа.
Я действительно ценю любую помощь с использованием JCurses или любой другой способ.
2 ответа
Эта программа работала для меня.
Вам нужно вызвать Toolkit.init(), чтобы перевести терминал в режим cbreak(). И не забудьте вызвать Toolkit.shutdown() перед выходом.
Пара недостатков.
- jcurses автоматически переводит tty в режим cbreak, а jcurses не предоставляет метод для непосредственного управления библиотекой curses.
- как только вы находитесь в jcurses, вывод находится в режиме cbreak, и прямые строки из java имеют переводы строк, но не возвращают каретки.
- разработчики jcurses реализовали только проклятие части владения целым экраном. Jcurses кажется излишним, если все, что вам нужно, это режим Cbreak.
Программа.
import jcurses.system.CharColor;
import jcurses.system.InputChar;
import jcurses.system.Toolkit;
public class itest
{
public static void main(String[] args)
{
int y = 0;
CharColor color = new CharColor(CharColor.BLACK, CharColor.WHITE);
Toolkit.init();
while (true) {
InputChar c = Toolkit.readCharacter();
if ('q' == c.getCharacter())
break;
Toolkit.printString(String.format("c : %c", c.getCharacter()), 0, y++, color);
}
Toolkit.shutdown();
}
}
В Java Curses есть несколько специальных методов распознавания нажатий клавиш, но привязка себя к внешней библиотеке для одной функции может оказаться не лучшим решением.
То, что вам нужно, может быть достигнуто путем создания Swing-приложения в терминальном стиле и использования KeyListener
для обнаружения событий нажатия клавиш. Тем не менее, MadProgrammer отмечает в " Как заставить esc остановить метод", что такое решение может иметь "проблемы с фокусом".
Поэтому, если вы хотите отслеживать конкретные нажатия клавиш или влиять на поведение программы, основываясь на различных пользовательских вводах, я бы рекомендовал использовать привязки клавиш, которые реализованы как часть Swing.
например
component.getInputMap(WHEN_IN_FOCUSED_WINDOW).put
(KeyStroke.getKeyStroke("F1"),"actionName");
component.getActionMap().put("actionName", yourAction);
Где компонент любой JComponent
объект (предположительно, дисплей терминала), и yourAction
это любое свинг-действие. Использование параматеризованной формы getInputMap()
как показано здесь, предпочтительнее для "консольного" приложения, так как пользователь будет обязательно делать нажатия клавиш в окне верхнего уровня, и поэтому фокус компонента не имеет значения.