简体   繁体   English

Java,在执行的jButton动作中读取输入流

[英]Java, reading input stream inside jButton actionperformed

I am trying to read an input stream of a process that I create inside an actionPerformed function of a JButton for my interface. 我正在尝试读取我在接口的JButtonactionPerformed函数内部创建的过程的输入流。 For that purpose, I have implemented a runnable class. 为此,我实现了一个可运行的类。 The problem is that I get an output stream in quantas, meaning that, lets say I get 50 lines, than a big pause, and 50 lines more and such. 问题是我得到了一个以量子为单位的输出流,这意味着,我得到的是50行而不是一个大的停顿,还有50行之多。 The bigger problem is that the order of lines are not consistent. 更大的问题是线的顺序不一致。 Here is what my code looks like... 这是我的代码看起来像...

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt)
{
  try{
    String sCommand = "cmd /c \"myenvsetup.bat && myprogram.exe\"";
    Runtime rt = Runtime.getRuntime();
    pr = rt.exec(sCommand);
    java.awt.EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try{
          BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
          String line = null;
          while((line = input.readLine()) != null){
            jTextArea1.append(line + "\n");
            jTextArea1.scrollRectToVisible(new Rectangle(0, jTextArea1.getHeight(), 0, 0));
            jTextArea1.update(jTextArea1.getGraphics());
          }
          pr.waitFor();
        } catch (Exception e) {
        }
      }
    });
  } catch (Exception e){
  }
}

In short you shouldn't do any blocking I/O in the event thread. 简而言之,您不应在事件线程中执行任何阻塞的I / O。 Use another thread, 使用另一个线程,

You should use a swing worker. 您应该使用秋千工人。 I have written an example using an executor to do the IO. 我已经编写了一个使用执行程序执行IO的示例。

ExecutorService executor = newSingleThreadExecutor()

The purpose of this example is to show, you do your work on the executor thread, and then you post your changes to the EDT. 本示例的目的是显示您在执行程序线程上进行工作,然后将更改发布到EDT。

try {
    String sCommand = "cmd /c \"myenvsetup.bat && myprogram.exe\"";
    Runtime rt = Runtime.getRuntime();
    pr = rt.exec(sCommand);
    executor.submit(new Runnable() {
      public void run(){
        try{
            BufferedReader input = new BufferedReader(
              new InputStreamReader(pr.getInputStream())
            );
            String line = null;
            while((line = input.readLine()) != null){
                final String l = line;
                EventQueue.invokeLater(new Runnable(){
                  @Override
                  public void run(){
                     jTextArea1.append(l + "\n");
                     jTextArea1.scrollRectToVisible(
                       new Rectangle(0, jTextArea1.getHeight(), 0, 0)
                     );
                     jTextArea1.repaint();
                 }
                });
              }
              pr.waitFor();
        } catch (Exception e) {}
      }
   });
} catch (Exception e){
}

The SwingWorker class takes care of doing work off of the EDT and allowing you to publish the work. SwingWorker类负责在EDT之外进行工作,并允许您发布工作。 It is more appropriate for this situation. 更适合这种情况。

And you shouldn't use .update(Graphics g). 而且您不应该使用.update(Graphics g)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM