最近,我试图将普通终端的功能实现到图形设计的基于Swing的控制台项目。我喜欢这里的一些人如何使这成为可能,但我偶然发现了另一个大问题。有些人实际上谈到InpuStreamListener
虽然我不太喜欢这个。我的工作的示例代码(几乎不是我的,但它是我的应用程序的源代码)将是以下内容:
// Making an executor
org.apache.commons.exec.DefaultExecutor exec = new org.apache.commons.exec.DefaultExecutor();
// Creating the streams (pretty much ignore this, I just include it as a general idea of the method)
consoleOutputStream = new ConsoleOutputStream();
consoleInputStream = new JTextFieldInputStream(gsc.mainWindow.getConsoleInput().getJTextField());
// Stream Handler with the customized streams I use for the process
org.apache.commons.exec.PumpStreamHandler streamHandler = new org.apache.commons.exec.PumpStreamHandler(consoleOutputStream, consoleOutputStream, consoleInputStream);
// Setting the handler and finally making command line and executing
exec.setStreamHandler(streamHandler);
org.apache.commons.exec.CommandLine commandline = org.apache.commons.exec.CommandLine.parse(String.valueOf(arg));
exec.execute(commandline);
现在问题是我通常尝试通过这个方法通过java命令运行java应用程序。 OutputStream
工作得非常好,没有任何缺陷并且给了我所有的能力,但是输入的应用程序给我带来了很多麻烦。我认为这个问题存在于System.in
,Scanner
类,Console
类等的硬编码中。所以这就是我需要一些帮助(最后):
我想要么能够直接访问传递给我的应用程序的InputStream
,或者有人向我解释如何实际编写InputStreamListener
,当我运行外部Java应用程序时偶尔会使用InputStream
(是的) ,我通过我的界面而不是cmd或终端运行它们,我试图在这里制作一个工具)。如果这太复杂了,需要在我身边进行大量的调整,或者通常是不可能的,有人可以帮助我获得传递{{1}}所以我实际上可以写一个允许我编写特定应用程序的类我的界面?
提前致谢,非常感谢您花时间阅读整篇文章! :)
答案 0 :(得分:0)
假设这些Apache库实现了InputStream
和OutputStream
接口,您可以使用PipedInputStream
和PipedOutputStream
来访问信息。这是一个简单的例子:
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class InputRedirection extends Box{
public InputRedirection() {
super(BoxLayout.X_AXIS);
//Remap input
//Create the input stream to be used as standard in
final PipedInputStream pisIN = new PipedInputStream();
//Create an end so we can put info into standard in
PipedOutputStream posIN = new PipedOutputStream();
//Wrap with a writer (for ease of use)
final BufferedWriter standardIn = new BufferedWriter(new OutputStreamWriter(posIN));
//Set standard in to use this stream
System.setIn(pisIN);
//Connect the pipes
try {
pisIN.connect(posIN);
} catch (IOException e2) {
e2.printStackTrace();
}
//UI element where we're entering standard in
final JTextField field = new JTextField(20);
ActionListener sendText = new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
try {
//Transfering the text to the Standard Input stream
standardIn.append(field.getText());
standardIn.flush();
field.setText("");
field.requestFocus();
} catch (IOException e) {
e.printStackTrace();
}
}};
field.addActionListener(sendText);
add(field);
//Why not - now it looks like a real messaging system
JButton button = new JButton("Send");
button.addActionListener(sendText);
add(button);
//Something using standard in
//Prints everything from standard in to standard out.
Thread standardInReader = new Thread(new Runnable(){
@Override
public void run() {
boolean update = false;
final StringBuffer s = new StringBuffer();
while(true){
try {
BufferedInputStream stream = new BufferedInputStream(System.in);
while(stream.available() > 0){
int charCode = stream.read();
s.append(Character.toChars(charCode));
update = true;
}
if(update){
//Print whatever was retrieved from standard in to standard out.
System.out.println(s.toString());
s.delete(0, s.length());
update = false;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}});
standardInReader.start();
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new InputRedirection());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
哦 - 在使用PipedStreams时要考虑一件事:只有一个线程可以写入输出,只有一个可以从输入读取。否则你会遇到一些时髦的问题(详见http://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/)。