Java控制台输出重叠Scanner

时间:2018-04-22 18:27:30

标签: java

我试图创建一个控制台输入系统,同时能够打印输出:

new Thread(() ->{ //asynchronous output test every 2 sec
        while(true) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("test");
        }
    }).start();

这是我获取用户输入的方式:

String line = scanner.nextLine();

然而,当我打字并同时输出时,结果就是这样:

Test
Test
TestI'm try
Testing to type

有没有办法在控制台底部显示输入行?

1 个答案:

答案 0 :(得分:2)

解决方案是在每次输入和存储实际写入变量的内容时获取用户的输入。然后,在编写“测试”之前,通过在控制台中多次打印\b来清除用户输入的字符数量。之后,您可以再次打印用户的输入,使其感觉上面刚刚打印出“测试”。

棘手的部分是在输入时获取用户的输入。我使用JLine lib来实现这一目标。此外,我确保“测试”打印线程以同步方式获取inputLine以确保线程安全。

private static String inputLine = "";

synchronized static String getInputLine() {
    return inputLine;
}

synchronized static void setInputLine(String line) {
    inputLine = line;
}

public static void main(String[] args) {

    char c;
    char allowed[] = {'a','b','c','d','e','f','g','h','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','\n','\r','\b'};

    ConsoleReader reader;
    PrintWriter out = new PrintWriter(System.out);

    new Thread(() ->{ //Asynchronous output test every 2 sec
        while(true) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String erase = ""; //Prepare a string as long as the input made \b characters
            for(int i = 0 ; i < getInputLine().length() ; i++)
                erase += '\b';

            String whitespace = ""; //Prepare a string of whitespaces to override the characters after "test" (thus -4)  
            for(int i = 0 ; i < getInputLine().length() - 4 ; i++)
                whitespace += ' ';

            out.print(erase); //Erase the input line                
            out.println("test" + whitespace);
            out.print(getInputLine());
            out.flush();
        }
    }).start();

    try {
        reader = new ConsoleReader();
        reader.setBellEnabled(false);

        while(true){
            c = (char) reader.readCharacter(allowed);

            if(c == '\r' || c == '\n') {

                //Do something with the input

                setInputLine("");
                out.println();
            } else if(c == '\b') { //Backspace
                String line = getInputLine();
                setInputLine(line.substring(0, line.length()-1));
                out.print(c);
                out.print(" "); //Print whitespace to erase trailing char
                out.print(c); //Backspace again to send the carret back to the last char
            } else {
                setInputLine(getInputLine() + c);
                out.print(c);
            }

            out.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

此程序适用于我,但仅限于我的IDE之外。请注意,程序停留在无限循环中,因此如果要关闭它,则必须使用“quit”命令从代码中处理它。

编辑:还以同步方式设置inputLine。