Чтение с клавиатуры без нажатия "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() как показано здесь, предпочтительнее для "консольного" приложения, так как пользователь будет обязательно делать нажатия клавиш в окне верхнего уровня, и поэтому фокус компонента не имеет значения.

Другие вопросы по тегам