Как перехватить событие нажатия клавиатуры в консоли?

Рейтинг: 1Ответов: 1Опубликовано: 26.11.2014

Суть проблемы: есть некая программа, которая опрашивает устройство, в зависимости от ответа выполняет некие действия.

Но нужно дать возможность самостоятельно выполнять ограниченное количество действий с помощью "горячих" кнопок, например, банально завершить выполнение программы при нажатии клавиши х.

...
public class Main {
    public static void main(String[] args) {
        Devices d = new Devices();
        while(true) {
            if (!d.pollDevice()) { break; }
        }
    }
}
...

Если добавить Scanner либо InputStreamReade, программа останавливается и ждет нажатия.

Ответы

▲ 2Принят

А почему бы вам не читать пользовательский ввод в отдельном потоке?

public class Main implements Runnable {

    private static boolean isRunning = true;

    public void run() {
        Scanner s = new Scanner(System.in);
        while (isRunning) {
            int i = s.nextInt();
            if (i == 1) {
                isRunning = false;
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new Main()).start();
        while (isRunning) {
            System.out.println("Running...");
        }
    }
}

Такой код не будет приостанавливать выполнение основного потока для чтения данных.

Обновление

Тут ничего не сделаешь, кроссплатформенного способа заставить Java реагировать на нажатия клавиш в консоли нет. В unix-like ОС есть возможность перевести консоль из построчного в посимвольный режим ввода, но в консоли Windows такого не предусмотрено. Можно прикрутить нативный модуль, однако, это также убьет кроссплатформенность. Ещё можно переписать приложение на графический UI фреймворк вроде Swing, там есть возможность кроссплатформенного отслеживания нажатия клавиш, но скорее всего это не то, чего хотел автор вопроса.