我有几个小应用程序,它们使用标准控制台来检索用户输入,并显示out、system.in和system.out中的消息。
现在我想实现一些从这些应用程序调用的基于Swing的类,它显示一个有两个文本区域的框架,一个用于输入(因此与System.in相关联),另一个(不可编辑)显示消息(因此与System.out相关联)。实际上我已经实现了all,(实际上创建一个简单的基于swing的gui并从event dispatcher线程启动它并不那么复杂,将all导出为jar并将其作为库包含在原始项目中也是如此)。到目前为止,我遇到的唯一问题是将标准的System.in和System.out交换到一些与2JTextarea
相关联的自定义的问题。实际上,我在网上检查了一些解决方案,最后得到了以下几行代码:
我使用2个PipedInputStream和一个printwriter:
private final PipedInputStream inPipe = new PipedInputStream();
private final PipedInputStream outPipe = new PipedInputStream();
private PrintWriter inWriter;
然后我交换溪流
System.setIn(inPipe);
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
为了从outPipe中检索数据,我使用SwingWorker
,其doinbackgroud
方法通过扫描器
从outPipe中读取行并发布它们,以便在不可编辑的Jtextarea中追加这些行字符串。同时,KeyListener
检查vk_enter
单击,以便从用作提示符的JTextField中获取文本,一旦发生这种情况,文本将使用System.out本身显示,并且它实际上显示在前面的JTextArea中,因此上面描述的SwingWorker工作,然后我在inWriter中写入了相同的文本行(PrintStream
对象关联到与System.in相关的管道),因此可以从原始应用程序中存在的Reader对象中读取该行。
不幸的是,这是代码中唯一不起作用的部分。实际上,一旦我启动了新的gui控制台,然后更改流,原始应用程序将只显示它在System.Out上打印的文本,但是当它想读取用户写入的文本时,例如从BufferedReader或Scanner对象读取,什么也不会发生,就像in流是空的一样。
我认为这是由于SwingWorker doInBackground方法中的扫描器,因为当它读取outPipe上的下一行时,它也会清理流本身。有什么办法可以解决这个问题吗?我知道我可以编写处理输入和输出的新方法,但我希望保留这种非侵入性的方法,因此无需编辑原始代码,在原始应用程序main方法中创建gui控制台对象就可以了。提前谢了。
更新1
public class Console extends JFrame implements KeyListener
{
private JTextField prompt;
private JTextArea log;
private final PipedInputStream inPipe = new PipedInputStream();
private final PipedInputStream outPipe = new PipedInputStream();
private PrintWriter inWriter;
public Console(String title)
{
super(title);
System.setIn(inPipe);
try
{
System.setOut(new PrintStream(new PipedOutputStream(outPipe), true));
inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);
}
catch(IOException e)
{
System.out.println("Error: " + e);
return;
}
JPanel p = new JPanel();
p.setLayout(null);
log = new JTextArea();
log.setEditable(false);
log.setBounds(10, 10, 345, 250);
p.add(log);
prompt = new JTextField();
prompt.setBounds(10, 270, 356, 80);
prompt.addKeyListener(this);
p.add(prompt);
getContentPane().add(p);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(392, 400);
setLocationRelativeTo(null);
(new SwingWorker<Void, String>()
{
protected Void doInBackground() throws Exception
{
Scanner s = new Scanner(outPipe);
while (s.hasNextLine())
{
String line = s.nextLine();
publish(line);
}
return null;
}
@Override
protected void process(java.util.List<String> chunks)
{
for (String line : chunks)
{
if (line.length() < 1)
continue;
log.append(line.trim() + "\n");
}
}
}).execute();
}
public void execute()
{
String text = prompt.getText();
prompt.setText("");
System.out.println(text);
inWriter.print(text.trim().replaceAll("\r\n", ""));
}
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
@Override
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
@Override
public void keyTyped(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
execute();
}
// this is the method called from the original application
public static void setConsole(final String title)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new Console(title);
//System.out.println("somewhat");
}
});
}
}
我自己找到了解决方案,实际上第一篇文章中发布的所有代码几乎都是正确的,问题在于从系统中读取。在最初的程序中,因为它是用scanner
对象完成的(但我也用BufferedReader测试了它),所以它似乎与字符串终止有关,因为如果我使用简单的system.in.read()
调用读取,我得到了正确的数据,当然是逐字符的。因为scanner
方法和read
方法都是I/O阻塞,所以我认为这与字符串的终止有关。因为当我在InputStream上编写它时,我从任何LF和CF字符中清除了字符串,正如您在上面的代码中所看到的那样,所以当调用println
时,只应该追加一个\r\n。但是一个字符一个字符地读结果,我看到\r\n\r\n在结尾,所以我想它应该是与字符串结尾有关的东西,即使我不能找到处理它的正确方法。我会随时更新你的信息,但如果你有建议和/或反馈,他们显然是受欢迎的。
问题内容: 如何使用Maven创建桌面(独立/ Swing)应用程序? 我正在使用Eclipse 3.6。 问题答案: 创建一个Maven项目,如下所示: 将以下条目添加到您的pom文件中: 将项目作为Maven项目导入到Eclipse,然后作为Java应用程序运行。
我正在试图弄清楚如何构建一个Spring Boot独立应用程序。当然,要让东西自动连线需要一些初始的上下文起点。如果我只是尝试自动生成一个类来运行一个作业,那么即使我将它设置为静态,它也是空的。 有没有办法在一个独立的非Web应用程序中使用Spring@Services? 因此,首先将静态JobRunnerService连接到运行MyApplication的主程序,JobRunner(Servic
问题内容: 所有, 我已经用Java编写了基于命令行的PhoneBook应用程序。该应用程序基本上会询问用户的一些详细信息,例如姓名,年龄,地址和电话号码,并将它们存储在文件中。其他操作包括按名称,电话号码等查找电话簿。所有详细信息都通过控制台输入。 我正在尝试为我已实现的每个功能编写JUnit测试用例,但无法弄清楚如何将实现代码重定向到我的JUnit测试方法中的某个东西,当我的实际代码停止供用户
请帮帮我,我用两个外部jar文件开发了一个简单的应用程序。在清理和构建的同时,它为应用程序和dist目录中的库文件夹创建了一个jar文件。当我尝试作为jar执行时,它执行得很完美
问题内容: 我想在nodejs中建立一个代码编辑器。有一些选项,例如使用Express Server显示编辑器并在后端执行代码。但这需要浏览器。因此,我正在寻找可以为Windows平台提供独立GUI的节点模块。 问题答案: 有两种不同的选择,具体取决于您要如何进行。 选项1: 使用QT或GTK绑定之类的东西来制作更传统的GUI应用程序。这些选项通常只是Node绑定到GTK和QT公开的C / C +
问题内容: 我正在考虑开发由两部分组成的桌面应用程序: 用户界面(例如Java应用) 后端Node.js服务器 2个部分通过插座连接。不要问为什么我知道这很奇怪。 我将希望能够为客户提供带有安装程序的应用程序。我不希望用户必须自己安装Node.js。 有没有一种方法可以独立安装Node.js服务器,即无需在系统上全局安装Node.js。 对于任何(Windows,Linux,Mac OS X …)