0

I am trying to read an input stream of a process that I create inside an actionPerformed function of a JButton for my interface. 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. 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){
  }
}
Endery
  • 1,090
  • 17
  • 31
  • 1
    For [example](http://stackoverflow.com/questions/30797851/update-jlabel-content-from-the-output-of-shell-script/30798684#30798684), [example](http://stackoverflow.com/questions/34858405/how-can-i-make-this-method-update-the-gui-within-my-loop/34864911#34864911), [example](http://stackoverflow.com/questions/15801069/printing-a-java-inputstream-from-a-process/15801490#15801490). The probable cause is the call to `update`, which you should never had to do – MadProgrammer Mar 15 '16 at 10:58

2 Answers2

0

In short you shouldn't do any blocking I/O in the event thread. Use another thread,

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I also tried that. I implemented a runnable class and created a new thread right after i executed the program. Still the same output. – thisiserdinc Mar 15 '16 at 09:21
0

You should use a swing worker. I have written an example using an executor to do the 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.

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. It is more appropriate for this situation.

And you shouldn't use .update(Graphics g).

matt
  • 10,892
  • 3
  • 22
  • 34