Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中创建独立的gui控制台,扩展基于提示符的应用程序_Java_Swing_User Interface_Stream_Console - Fatal编程技术网

在java中创建独立的gui控制台,扩展基于提示符的应用程序

在java中创建独立的gui控制台,扩展基于提示符的应用程序,java,swing,user-interface,stream,console,Java,Swing,User Interface,Stream,Console,我有几个小应用程序,它们使用标准控制台检索用户输入并显示消息troughtout System.in和System.out 现在我想实现一些从这些应用程序调用的基于Swing的类,它显示了一个包含2个文本区域的框架,一个用于输入(与System.in关联),另一个用于显示消息(因此与System.out关联)的框架(不可编辑)。实际上,我已经实现了所有(实际上,创建一个简单的基于swing的gui并从event dispatcher线程启动它并不是那么复杂,将所有内容导出为jar并将其作为库包含

我有几个小应用程序,它们使用标准控制台检索用户输入并显示消息troughtout System.in和System.out

现在我想实现一些从这些应用程序调用的基于Swing的类,它显示了一个包含2个文本区域的框架,一个用于输入(与System.in关联),另一个用于显示消息(因此与System.out关联)的框架(不可编辑)。实际上,我已经实现了所有(实际上,创建一个简单的基于swing的gui并从event dispatcher线程启动它并不是那么复杂,将所有内容导出为jar并将其作为库包含在原始项目中也是如此)。到目前为止,我遇到的唯一问题是将标准System.in和System.out交换到一些与2
JTextArea
相关的自定义System.in和System.out。实际上,我在网上查看了一些解决方案,最后得到了以下几行代码:

我使用2个PipedInputStream和一个PrintWriter:

然后我交换小溪

为了从输出管中检索数据,我使用了一个
SwingWorker
,其
DoinBackground
方法Troughout一个
扫描器从输出管中读取行并发布它们,以便将这些行字符串附加到一个不可编辑的JTextArea中。
同时,
keyListener
检查
VK_ENTER
点击以从用作提示的JTextField中获取文本,一旦发生这种情况,文本将使用System.out本身显示,并有效地显示在前面的JTextArea中,因此上述SwingWorker工作,然后我在inWriter中写入了同一行文本(与System.in相关的管道关联的
PrintStream
对象),因此该行应该可以从原始应用程序中存在的Reader对象中读取

不幸的是,这是代码中唯一不起作用的部分。事实上,一旦我启动新的gui控制台,然后更改流,原始应用程序将只显示它在System.out上打印的文本,但是当它想要读取用户写入的文本时,例如,Troughout一个BufferedReader或一个Scanner对象,任何事情都不会发生,就好像流中的文本是空的一样

我认为这是由于SwingWorker doInBackground方法中的扫描仪,因为当它读取输出管道上的下一行时,它也会清理流本身。有没有办法解决这个问题?我知道我可以编写新的方法来处理输入和输出,但我希望保持这种非侵入性方法,因此不必编辑原始代码,这是在原始应用程序主方法中创建gui控制台对象的一部分。提前谢谢

更新1

这是控制台类,所有操作都在这里完成

公共类控制台扩展JFrame实现KeyListener
{
私有JTextField提示符;
私人区域日志;
私有最终PipedInputStream inPipe=新PipedInputStream();
private final PipedInputStream outPipe=new PipedInputStream();
私人印刷作家;
公共控制台(字符串标题)
{
超级(标题);
系统设置(输入管道);
尝试
{
系统放样(新打印流(新管道输出流(输出管),真));
inWriter=新的PrintWriter(新的管道输出流(inPipe),true);
}
捕获(IOE异常)
{
System.out.println(“错误:+e”);
返回;
}
JPanel p=新的JPanel();
p、 setLayout(空);
log=新的JTextArea();
log.setEditable(false);
对数立根(10,10345250);
p、 添加(日志);
prompt=newjtextfield();
提示.后退(1027035680);
prompt.addKeyListener(this);
p、 添加(提示);
getContentPane().add(p);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(真);
设置大小(392400);
setLocationRelativeTo(空);
(新SwingWorker()
{ 
受保护的Void doInBackground()引发异常
{ 
扫描仪s=新扫描仪(输出管);
而(s.hasNextLine())
{
字符串行=s.nextLine();
出版(行);
}
返回null;
} 
@凌驾
受保护的void进程(java.util.List块)
{ 
for(字符串行:块)
{
if(line.length()<1)
继续;
log.append(line.trim()+“\n”);
}
} 
}).execute();
}
public void execute()
{
String text=prompt.getText();
prompt.setText(“”);
System.out.println(文本);
inWriter.print(text.trim();
}
@凌驾
按下公共无效键(按键事件e)
{
如果(例如getKeyCode()==KeyEvent.VK_ENTER)
执行();
}
@凌驾
公共无效密钥已释放(密钥事件e)
{
如果(例如getKeyCode()==KeyEvent.VK_ENTER)
执行();
}
@凌驾
public void keyTyped(KeyEvent e)
{
如果(例如getKeyCode()==KeyEvent.VK_ENTER)
执行();
}
//这是从原始应用程序调用的方法
公共静态void setConsole(最终字符串标题)
{
invokeLater(新的Runnable()
{
公开募捐
{
新控制台(标题);
//System.out.println(“多少”);
}
});
}
}

我自己找到了解决方案,实际上第一篇文章中发布的所有代码几乎都是正确的,问题在于从系统读取。在原始程序中,因为它是用
扫描仪
对象完成的(但我也用BufferedReader进行了测试)这似乎与字符串终止有关,因为如果我使用一个简单的
System.in.read()
调用进行读取,我就得到了正确的数据,当然是逐字符读取的。由于
Scanner
方法和
read
方法都是I/O阻塞,我认为这与字符串的终止有关。因为当
    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);