2012-10-04 13 views
3

最近我试图将一个普通终端的功能实现为一个图形化设计的基于Swing的控制台项目。我喜欢这里的一些人如何做到这一点,但我偶然发现了另一个大问题。有些人实际上谈到了InpuStreamListener,虽然我不太喜欢这个。我工作的一个示例代码(几乎不完全矿,但它是我的应用程序的源代码)将是以下几点:获取并使用应用程序传递的InputStream

// 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工作得很好,没有任何缺陷,并给我所有它应该,但与输入应用程序给我很多麻烦。我beieve问题居住在硬编码System.in,Scanner类,Console类等。所以这里是我需要一些帮助(最后): 我想要能够直接访问传递给我的应用程序或某人InputStream向我解释了如何实际编写一个InputStreamListener,当我运行外部java应用程序(是的,我通过我的界面而不是cmd或终端运行它们,我试图在这里创建一个工具)时,它会偶尔使用。如果这太复杂了,需要在我身边进行很多调整,或者通常是不可能的,有人可以帮助我获得传递的InputStream,所以我实际上可以编写一个类来允许我编写特定于我的界面的应用程序?

在此先感谢,甚至非常感谢您花时间阅读全文! :)

+0

不管谁知道为什么'event-dispatch-thread'标签被@mKorbel编辑,他们能解释它吗?谢谢! :) –

+0

所有事件到AWT,Swing GUI必须在事件派发上完成Tread – mKorbel

回答

0

假设这些Apache库实现了InputStreamOutputStream接口,您可以使用PipedInputStreamPipedOutputStream来访问信息。这里有一个简单的例子:

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/)。

+0

你让我错了:我的'consoleOutputStream'是'OutputStream'的扩展,它已经工作并打印硬编码的应用程序的输出要在'System.out'中打印的应用程序。这个功能正是我在'consoleInputStream'变量中安装的'InputStream'扩展所需要的。基本上我只想使用InputStream,输出已经很好,而且管道并不是我最好的选择,我猜想之前提出的InputStreamListener可以做到,但仍然不是我需要的最佳选择......:/ –

+0

以前是http://stackoverflow.com/a/12669494/1650200其中写在这篇文章中的类是'consoleInputStream'的对象的类型。我需要的是一种使用这个类的方法,它可以作为任何Java应用程序的输入类。管道似乎有点笨拙,因为我已经在另一个Java应用程序中运行一个Java应用程序,并且如果不小心,线程可能很容易被搞砸,所以如果还有一个问题,我希望更多的最佳解决方案!无论如何,谢谢你的建议! :) –

+0

是的 - 重定向System.in几乎是以相同的方式完成,只是向后。我使用System.out是因为它更容易演示。我会用System.in更新我的例子,因为我有时间。就线程而言,Pipes不会太难以使用/防止混淆 - 我怀疑这对您来说是一个问题。 –

相关问题