计算机控制台java,使用jLine的Java控制台应用程序(Java Console Application with jLine)

使用jLine的Java控制台应用程序(Java Console Application with jLine)

我有一个多线程java控制台应用程序。 其中一个线程是从用户读取输入,而其他线程则向控制台打印一些数据。 当用户输入输入时,当作者线程打印某些内容时,问题就出现了。 它会中断用户。

我在输出的开头写了“\ r”来清除线条以获得更好的效果。 但是,我还要打印到下一行用户键入的内容,直到那一刻。

例如,我想输入123456作为输入。 但是当我键入123时,

>123

编写器线程打印“OUTPUT”。

>OUTPUT

>

我想显示我之前输入的内容(“123”),然后我将输入剩余的输入。

>OUTPUT

>123

我被建议使用jLine。 但我无法实现它。 您能通过提供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.

原文:https://stackoverflow.com/questions/38942758

更新时间:2020-06-22 15:06

最满意答案

你必须做这样的事情:

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”转义命令清除它。

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.

相关问答

你似乎在正确的轨道上。 我认为做到这一点的“正确”方式是一个工作线程,将所有阻塞I / O转移到非阻塞队列中。 请看java.util.concurrent中的ConcurrentLinkedQueue 。 You seem to be on the right track. I think the "right" way to do this is a worker thread that pours all the blocking I/O into a non-blocking queue.

...

我放弃了尝试仅使用java工具进行测试,并使用python pexpect库来执行控制台应用程序。 测试已集成到maven构建中,但需要* nix主机来运行它们: import unittest

import pexpect

import os

import signal

import subprocess

import urllib

import urllib2

import json

from wiremock import WiremockClient

class TestInterac

...

当您使用Runtime.exec()执行外部进程时,其标准输入和输出流未连接到运行Java程序的终端。 你可以使用shell重定向来连接它,但首先你需要知道使用哪个终端。 没有办法使用标准API来查找终端,但是可能您可以找到一个可以实现它的开源库。 为了看到它可以完成,这个程序以less打开自己: public class Test {

public static void main(String[] args) throws Exception {

Process p =

...

是的,我相信它应该。 根据我的经验:一旦程序开始运行,它就会执行它的编程。 Java程序不关心用户是否可以查看或与之交互。 Yes, I believe it should. In my experience: Once the program starts to run, it does what it was programmed to do. The Java program doesn't care if the user can see or interact with it.

好吧,我终于想出了以下内容(该类ConsoleReader ): public boolean showPassword(String pass, int millis) {

try {

resetPromptLine(" password>", pass, pass.length());

Thread.sleep(millis);

if (setCursorPosition(0) && killLine()) resetPromptLi

...

你必须做这样的事情: private synchronized static void println(ConsoleReader in, String text) throws IOException {

in.printString("\r");

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

in.redrawLine();

in.flushConsole();

}

它将覆盖现有的提示和用户输入,追加新行,然后重新绘制下面的提示和用户输入。 你

...

右键单击您的项目名称,然后从菜单中选择“属性”。 该窗口中的其中一个选项卡可让您设置命令行参数。 我不记得我头顶的确切一个。 Right click on your project's name and select "Properties" from the menu. One of the tabs in that window lets you set command-line arguments. I don't recall the exact one off the top of my

...

最近(最近)发布了Spring Shell 。 这就是Spring用来为他们的Roo外壳减去Roo部件的动力。 您可以将自己的命令插入其中,并利用其记录脚本,回放脚本,获取参数,更改提示等的功能。 我查看了随附的示例,它有四个不同的类,添加或更改了各种各样的东西,它看起来非常简单。 There's the recently (very recently) released Spring Shell. It's what Spring used to power their Roo shell mi

...

不直接。 Jcurses可能会诀窍,但包含本机代码。 Not directly. Jcurses will probably do the trick, but contains native code.

所有问题都是Sender和Reader程序以随机顺序连接到主程序,因此添加Thread.sleep(200)解决了我的问题,抱歉烦人。 PS:如果你用java(和cmd)编程,试试吧,我觉得我很开心。 All the problem was that the Sender and Reader programms conected in a random order to the main program, so adding Thread.sleep(200) resolved my probl

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值