javaconsole-applicationjlinejline2

Java Console Application with jLine


I have a multi thread java console application. One of the threads is reading input from the user while other prints to the console some data. The problem shows up when the writer thread print something while user is typing an input. It interrupts the user.

I wrote "\r" to the beginning of output to clear the line for a better looking. However, I also want to print to the next line what user typed until that moment.

For example, I want to type 123456 as input. But when I typed 123,

>123

The writer threads prints "OUTPUT".

>OUTPUT
>

I want to show what I typed before("123") and then I will type the remaining input.

>OUTPUT
>123

I was suggested to use jLine. But I couldn't achieved it. Can you help me by providing example usage of jLine library or suggesting an alternative solution?

It is important to not block the writer thread. It must print the output when it arrived.


Solution

  • You have to do something like this:

    private synchronized static void println(ConsoleReader in, String text) throws IOException {
        in.printString("\r");
    
        in.printString(text + "\n");
    
        in.redrawLine();
        in.flushConsole();
    }
    

    It will overwrite existing prompt and user input, append new line and then redraw the prompt and user input underneath.

    You can use it like this:

    public static void main(String[] args) throws IOException {
        ConsoleReader in = new ConsoleReader();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        println(in, new Date().toString());
                        Thread.sleep(100);
                    } catch (IOException | InterruptedException e) {
                        throw new IllegalStateException(e);
                    }
                }
            }
    
        }.start();
        while (true) {
            in.readLine("> ");
        }
    }
    

    This has some issues. For example long input will "stick out" from beneath added text. You can clear it with backspaces or "\033[2K" escape command.