Почему нажатие любой клавиши не останавливается в цикле?

У меня есть этот метод в java, который я нашел здесь.

private void pressAnyKeyToContinue() {
     try {
         System.in.read();
     }  
        catch(Exception e) {}  
 }

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

private void keyMessage() {
    System.out.print("Press any key to continue...");
    pressAnyKeyToContinue();

И затем я использую этот метод здесь:

public void method() {
    message1();
    for (Class class : classes) {
        keyMessage();
    }   
}

У меня проблема в том, что когда я сначала вызываю метод(), он печатает.

Otuput: Press any key to continue...

Затем я нажимаю клавишу + ввод. Пока здесь все идеально, но потом печатает:

Output: Press any key to continue... //* times of the loop

Я имею в виду, что он не позволяет мне нажимать какие-либо клавиши. Он просто идет до конца цикла.

Спасибо за ответ и извините за мой английский. Я знаю, что это нехорошо.


person IvansAlvares    schedule 03.03.2019    source источник


Ответы (1)


Стандартная консольная java просто не может этого сделать. Все вводимые символы буферизуются до тех пор, пока вы не нажмете клавишу ввода, после чего все они будут доступны в System.in.

Итак, если вы зациклите свой код «нажмите любую клавишу», скажем, 5 раз, а я наберу предложение «привет!», ваш код все равно застрянет на первом, ожидая клавиши. Если я затем нажму Enter, все 5 циклов завершатся немедленно, и если вы вызовете waitForKey позже, он мгновенно вернет еще 2-3 раза (один раз для восклицательного знака и один раз для новой строки.. дважды, если в Windows, потому что их новые строки состоят из 2 символов).

TL;DR: вы не можете использовать System.in.read() для этого. Вообще.

Одно из решений состоит в том, чтобы попросить пользователя не нажимать «любую» клавишу, а нажимать клавишу «ввод», а затем использовать, например, вызов сканера next() после установки разделителя на новую строку или написать код, который продолжает вызывать System.in.read() до тех пор, пока не будет возвращает '\n':

private void pressEnterToContinue() {
    while (true) {
        int c;
        try {
            c = System.in.read();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (c == -1 || c == '\n') return;
    }
}
person rzwitserloot    schedule 03.03.2019
comment
Большое спасибо за ответ. Я попытаюсь. - person IvansAlvares; 04.03.2019