Консольное приложение Java с jLine

У меня есть многопоточное консольное приложение Java. Один из потоков читает входные данные от пользователя, а другой выводит на консоль некоторые данные. Проблема проявляется, когда поток писателя печатает что-то, пока пользователь печатает ввод. Это прерывает пользователя.

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

Например, я хочу ввести 123456 в качестве ввода. Но когда я набрал 123,

>123

Автор темы печатает "ВЫХОД".

>OUTPUT
>

Я хочу показать, что я набрал раньше ("123"), а затем я буду вводить оставшиеся данные.

>OUTPUT
>123

Мне предложили использовать jLine. Но я не смог этого достичь. Можете ли вы помочь мне, приведя пример использования библиотеки jLine или предложив альтернативное решение?

Важно не блокировать поток записи. Он должен распечатать вывод, когда он прибыл.

1 ответ

Решение

Вы должны сделать что-то вроде этого:

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

    in.printString(text + "\n");

    in.redrawLine();
    in.flushConsole();
}

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

Вы можете использовать это так:

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("> ");
    }
}

Это имеет некоторые проблемы. Например, длинный ввод будет "торчать" из-под добавленного текста. Вы можете очистить его с помощью клавиш возврата или "\033[2K" escape-команды.

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