将System.in重定向到swing组件

嘿伙计我正在使用Swing和Apache Commons制作终端应用程序。 我能够轻松地将System.outSystem.err重定向到JTextArea但是我如何为System.in做到这一点? 我是否需要覆盖Inputstream方法? 我是否需要将StringJTextArea转换为字节数组,然后将其传递给InputStream ? 代码示例会很好。

我最近尝试过同样的事情,这是我的代码:

 class TexfFieldStreamer extends InputStream implements ActionListener { private JTextField tf; private String str = null; private int pos = 0; public TexfFieldStreamer(JTextField jtf) { tf = jtf; } //gets triggered everytime that "Enter" is pressed on the textfield @Override public void actionPerformed(ActionEvent e) { str = tf.getText() + "\n"; pos = 0; tf.setText(""); synchronized (this) { //maybe this should only notify() as multiple threads may //be waiting for input and they would now race for input this.notifyAll(); } } @Override public int read() { //test if the available input has reached its end //and the EOS should be returned if(str != null && pos == str.length()){ str =null; //this is supposed to return -1 on "end of stream" //but I'm having a hard time locating the constant return java.io.StreamTokenizer.TT_EOF; } //no input available, block until more is available because that's //the behavior specified in the Javadocs while (str == null || pos >= str.length()) { try { //according to the docs read() should block until new input is available synchronized (this) { this.wait(); } } catch (InterruptedException ex) { ex.printStackTrace(); } } //read an additional character, return it and increment the index return str.charAt(pos++); } } 

并像这样使用它:

  JTextField tf = new JTextField(); TextFieldStreamer ts = new TextFieldStreamer(tf); //maybe this next line should be done in the TextFieldStreamer ctor //but that would cause a "leak a this from the ctor" warning tf.addActionListener(ts); System.setIn(ts); 

自编码Java以来​​已经有一段时间了,所以我可能不会对模式进行更新。 你应该也可以重载int available()但我的例子只包含最小值,以使它与BufferedReaderreadLine()函数一起使用。

编辑:为了使其适用于JTextField您必须使用implements KeyListener而不是implements ActionListener ,然后在TextArea上使用addKeyListener(...) 。 你需要的函数而不是actionPerformed(...)public void keyPressed(KeyEvent e)然后你必须测试if (e.getKeyCode() == e.VK_ENTER)而不是使用整个文本你只是使用光标前的最后一行的子字符串

 //ignores the special case of an empty line //so a test for \n before the Caret or the Caret still being at 0 is necessary int endpos = tf.getCaret().getMark(); int startpos = tf.getText().substring(0, endpos-1).lastIndexOf('\n')+1; 

输入字符串。 因为否则每次按Enter键都会读取整个TextArea。

你需要创建一个自己的InputStream实现,它从你想要的任何Swing组件获取它的输入…基本上有一个缓冲区,你可以从Swing组件复制文本,并作为InputStream的源(当然需要阻止如果没有可用的输入)。