Issues with invokeLater
Asked Answered
A

1

1

I'm having issues updating a JLabel value using invokeLater. I have a separate method outside of the main function that runs invokeLater, but when I click the search button to update the value, it's not updating in the same instance of the gui. I have to relaunch the gui in eclipse to get the value to change. I'm not sure what I'm doing wrong so any help is greatly appreciated. I'm running this method threadStart(); in the actionListener of the button. Here's the method

    private void threadStart() {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {

          testLabel.setText(CN);
        }

Here's the full class as a reference.

import java.awt.EventQueue;

import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.swing.JFrame;
import javax.swing.JButton;

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.GridLayout;

import javax.naming.ldap.LdapName;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import java.awt.Color;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JTextArea;
import javax.swing.JTable;

public class MISControlPanel {

    JFrame frame;
    static JTextField textField;
    private JTextField textField_1;
    final JTextArea textArea = new JTextArea();
    JLabel selectedComputerFromAD = new JLabel("testing");
    String sCurrentLine = null;
    String CN = null;
    JLabel testLabel = new JLabel("test");

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MISControlPanel window = new MISControlPanel();
                    window.frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     * 
     * @throws IOException
     * 
     * @wbp.parser.entryPoint
     */
    public MISControlPanel() throws IOException {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     * 
     * @throws IOException
     */
    private void initialize() throws IOException {
        frame = new JFrame();
        frame.getContentPane().setBackground(Color.LIGHT_GRAY);
        frame.getContentPane().setForeground(Color.RED);
        frame.setBounds(100, 100, 658, 618);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.setTitle("MIS Advanced Computerers");
        frame.setResizable(false);
        FileWriter fw = new FileWriter("C:\\Users\\anoc5f\\Desktop\\Output.txt");
        File tempFile = new File("myTempFile.txt");
        JButton searchComputerButton = new JButton("Search");
        searchComputerButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                threadStart();
                String line;
                BufferedWriter bw = null;
                BufferedWriter writer = null;
                try {
                    writer = new BufferedWriter(new FileWriter(tempFile));
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }


                String s = null;

                Process p = null;
                /*
                 * try { // p = Runtime.getRuntime().exec(
                 * "cmd /c start c:\\computerQuery.bat computerName"); } catch
                 * (IOException e1) { // TODO Auto-generated catch block
                 * e1.printStackTrace(); }
                 */
                try {

                    p = Runtime.getRuntime().exec("c:\\computerQuery.bat");

                } catch (IOException e1) {

                    // TODO Auto-generated catch block

                    e1.printStackTrace();

                }
                StringBuffer sbuffer = new StringBuffer();
                BufferedReader in = new BufferedReader(new InputStreamReader(p
                        .getInputStream()));

                try {

                    while ((line = in.readLine()) != null) {

                        System.out.println(line);

                        // textArea.append(line);

                        String dn = "CN=FDCD111304,OU=Workstations,OU=SIM,OU=Accounts,DC=FL,DC=NET";
                        LdapName ldapName = new LdapName(dn);
                        String commonName = (String) ldapName.getRdn(
                                ldapName.size() - 1).getValue();

                    }
                    ComputerQuery.sendParam();

                } catch (IOException e1) {

                    // TODO Auto-generated catch block

                    e1.printStackTrace();

                } catch (InvalidNameException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } finally

                {
                    try {
                        fw.close();

                    }

                    catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }

                try {

                    in.close();

                } catch (IOException e1) {

                    // TODO Auto-generated catch block

                    e1.printStackTrace();

                }

                ComputerQuery.sendParam();

                   SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                          testLabel.setText(CN);
                        }
                      });
            }
        });

        try (BufferedReader br = new BufferedReader(new FileReader(
                "resultofbatch.txt"))) {

            final Pattern PATTERN = Pattern.compile("CN=([^,]+).*");
            try {
                while ((sCurrentLine = br.readLine()) != null) {

                    String[] tokens = PATTERN.split(","); // This will return
                                                            // you a array,
                                                            // containing the
                                                            // string array
                                                            // splitted by what
                                                            // you write inside
                                                            // it.
                    // should be in your case the split, since they are
                    // seperated by ","
                    // System.out.println(sCurrentLine);
                    CN = sCurrentLine.split("CN=", -1)[1].split(",", -1)[0];

                    System.out.println(CN);
                    testLabel.setText(CN);
                }

            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        // SwingUtilities.invokeLater(updateCN());
        searchComputerButton.setBounds(419, 19, 89, 20);
        frame.getContentPane().add(searchComputerButton);

        textField = new JTextField();
        textField.setBounds(285, 19, 124, 20);
        frame.getContentPane().add(textField);
        textField.setColumns(10);

        JLabel lblComputerName = new JLabel("Computer Name:");
        lblComputerName.setForeground(Color.BLACK);
        lblComputerName.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblComputerName.setBounds(159, 13, 124, 29);
        frame.getContentPane().add(lblComputerName);

        JLabel lblSelectedComputer = new JLabel("Selected Computer:");
        lblSelectedComputer.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblSelectedComputer.setBounds(205, 78, 143, 30);
        frame.getContentPane().add(lblSelectedComputer);
        java.net.InetAddress localMachine = null;
        try {
            localMachine = java.net.InetAddress.getLocalHost();
        } catch (UnknownHostException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }

        textArea.setBackground(Color.GRAY);
        textArea.setForeground(Color.WHITE);
        textArea.setFont(textArea.getFont().deriveFont(Font.BOLD));
        textArea.setBounds(10, 387, 632, 191);
        textArea.setEditable(false); // might cause design view not to come up
        frame.getContentPane().add(textArea);

        JButton btnNewButton = new JButton("SSO REPAIR");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

            }
        });
        btnNewButton.setBounds(36, 183, 132, 23);
        frame.getContentPane().add(btnNewButton);

        JLabel lblNewLabel = new JLabel("Batch File Fixes");
        lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 12));
        lblNewLabel.setBounds(53, 158, 115, 14);
        frame.getContentPane().add(lblNewLabel);

        JLabel lblIpAddress = new JLabel("IP Address:");
        lblIpAddress.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblIpAddress.setBounds(261, 104, 102, 22);
        frame.getContentPane().add(lblIpAddress);

        JLabel label = null;
        try {
            label = new JLabel(Inet4Address.getLocalHost().getHostAddress()); // Get
                                                                                // User
                                                                                // ID
        } catch (UnknownHostException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        label.setFont(new Font("Tahoma", Font.BOLD, 14));
        label.setForeground(Color.RED);
        label.setBounds(349, 105, 99, 21);
        frame.getContentPane().add(label);

        JLabel lblPcCommunication = new JLabel("PC Communication");
        lblPcCommunication.setFont(new Font("Tahoma", Font.BOLD, 12));
        lblPcCommunication.setBounds(279, 158, 115, 14);
        frame.getContentPane().add(lblPcCommunication);

        JButton btnPingComputer = new JButton("PING");

        btnPingComputer.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
            }

        });

        btnPingComputer.setBounds(306, 183, 64, 23);
        frame.getContentPane().add(btnPingComputer);

        JButton remoteAssistanceButton = new JButton(
                "Remote Assistance by PC Name");
        remoteAssistanceButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            }
        });

        remoteAssistanceButton.setBounds(215, 251, 246, 23);
        frame.getContentPane().add(remoteAssistanceButton);

        JButton btnPingIndefinetely = new JButton("PING INDEFINETELY");
        btnPingIndefinetely.setBounds(260, 217, 156, 23);
        frame.getContentPane().add(btnPingIndefinetely);

        JButton btnRdcByIp = new JButton("RDC by IP Address");
        btnRdcByIp.setBounds(261, 353, 156, 23);
        frame.getContentPane().add(btnRdcByIp);

        JButton btnRdcByName = new JButton("RDC by PC Name");
        btnRdcByName.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            }
        });
        btnRdcByName.setBounds(248, 319, 180, 23);
        frame.getContentPane().add(btnRdcByName);

        JLabel lblLoggedInOpid = new JLabel("Logged in OPID:");
        lblLoggedInOpid.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblLoggedInOpid.setBounds(228, 127, 135, 20);
        frame.getContentPane().add(lblLoggedInOpid);

        JLabel lblNewLabel_1 = new JLabel(System.getProperty("user.name")
                .toUpperCase());
        lblNewLabel_1.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblNewLabel_1.setForeground(Color.RED);
        lblNewLabel_1.setBounds(348, 130, 86, 14);
        frame.getContentPane().add(lblNewLabel_1);

        JButton btnHiddenShare = new JButton("HIDDEN SHARE");
        btnHiddenShare.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            }
        });
        btnHiddenShare.setBounds(484, 183, 132, 23);
        frame.getContentPane().add(btnHiddenShare);

        JLabel lblAdditionalTools = new JLabel("Tools");
        lblAdditionalTools.setFont(new Font("Tahoma", Font.BOLD, 12));
        lblAdditionalTools.setBounds(526, 157, 126, 20);
        frame.getContentPane().add(lblAdditionalTools);

        JButton btnNewButton_1 = new JButton("Remote Assistance by IP Address");
        btnNewButton_1.setBounds(215, 285, 246, 23);
        frame.getContentPane().add(btnNewButton_1);

        JButton gpUpdate = new JButton("GP UPDATE");
        gpUpdate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            }
        });
        gpUpdate.setBounds(36, 217, 132, 23);
        frame.getContentPane().add(gpUpdate);

        JButton btnForced = new JButton("NURMED REG FIX");
        btnForced.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            }
        });
        btnForced.setBounds(36, 251, 132, 23);
        frame.getContentPane().add(btnForced);

        JButton btnCleaConsoler = new JButton("CLEAR");
        btnCleaConsoler.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                textArea.setText("");
            }
        });
        btnCleaConsoler.setBounds(563, 353, 79, 23);
        frame.getContentPane().add(btnCleaConsoler);

        JLabel lblOpid = new JLabel("Find Computer by OPID:");
        lblOpid.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblOpid.setBounds(104, 53, 180, 14);
        frame.getContentPane().add(lblOpid);

        textField_1 = new JTextField();
        textField_1.setBounds(285, 50, 124, 20);
        frame.getContentPane().add(textField_1);
        textField_1.setColumns(10);

        JButton btnNewButton_2 = new JButton("Search");
        btnNewButton_2.setBounds(419, 50, 89, 23);
        frame.getContentPane().add(btnNewButton_2);
        testLabel.setForeground(Color.RED);
        testLabel.setFont(new Font("Tahoma", Font.BOLD, 14));

        testLabel.setBounds(358, 78, 150, 24);
        frame.getContentPane().add(testLabel);

    }
    private void threadStart() {
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {

              testLabel.setText(CN);
            }
          });
        }

}

enter image description here

Absorbed answered 12/7, 2015 at 13:46 Comment(25)
Your "full class" does not have a testLabel field. Please clarify.Pavo
Ah, because you're not showing the MISControlPanel class, probably the most important bit of code </confused>Pavo
Oops. I added the wrong class. I updated the code above. It's the right class nowAbsorbed
Note 1) that your threadStart method is already being called on the Swing event thread, and so there is no reason for you to use SwingUtilities.invokeLater to queue the code on the event thread, and 2) the SwingUtilities.invokeLater call has nothing to do with your problem.Pavo
If invokeLater isn't the problem, then can you point out where in the code specifically the issue lies? You said that the threadStart method is being called on the swing event thread. It's being called in the actionListener. Is this what you mean?Absorbed
1) I have no idea where your problem lies given the code posted. You have posted a monstrous amount of code, most of it not related to your problem, and despite that still haven't posted the relevant code as far as I can see. Please consider creating and posting a Minimal, Complete, and Verifiable Example Program. 2) All invokeLater does is to queue the Runnable on the Swing event thread, and that action can't cause the problem that you describe. 3) Yes, code inside of an ActionListener is called on the Swing event thread.Pavo
And what does your input file look like, what is this code supposed to do? You do have parts of your code that should probably be run in a background thread or two, especially the file I/O code.Pavo
There's two gui's the MISSearch class and the MISControlPanel. The MISSearch class takes partial part of a computer name and performs an active directory query to grab the full computer name and outputs it to a txt file.Then I'm using buffered reader to pull the computer name from the txt file and updated the label to the computer name, but it's not updating in the same instance of the gui, I have to relaunch the gui to see the updated value. So if I search for 111222, the full computer name ccdd111222 should appear in the same instance of the gui in the label.Absorbed
1) Why are you writing to a file and not transferring data directly from one class to another? 2) Since your problem involves communication between two classes, you will likely need to post two classes, but I strongly recommend that when you do so, you simplify the code as much as possible so that it is a reasonable amount of code for volunteers to go through. 3) How does one class notify the other of the change in the file contents?Pavo
If your referring to the txt file that the computer name gets written to, I though the invoke later would check for an updated value within the file and then update accordingly. If not, is there a better way I don't know about?Absorbed
"I though the invoke later would check for an updated value within the file."??? -- where did you find documentation suggesting this? This is something that I've never heard of being associated with invoke later, and I thought that I was something of a Swing expert. If you have seen something documenting this functionality, please post a link, because again, it is something I have never seen and seems a bit, how to say, unusual. But again, why even use a file? Why not pass information directly from one object to another? The file bit seems a bit of a kludge.Pavo
I'm definitely not a Swing expert. So if this isn't possible I must of misread some documentation at some point. So how would you suggest I go about grabbing the updated value within the txt file and updating the label within the same instance of the gui? I'm using the file for getting the computer name from the active directory otherwise I can't query the active directory with java. It works, just doesn't update in the same instanceAbsorbed
This discussion is getting prolonged. Consider joining me briefly in chat if you desire.Pavo
I can't use the chat feature because it's blocked by the network I am on. I can use chatbox though if that works for youAbsorbed
It's OK. we can discuss here, and then later delete most discussion. But please tell -- why two GUI's instead of one? What do each do?Pavo
There's two Gui's postimg.org/image/8tiaq0ds9 The one on the left opens first and when you click search it opens the main gui. Originally it was only one, but I was having the issue of updating the label value with the current computer name in the txt file so I broke it up into two guis hoping that when the second gui opens,the value will change. I thought it might act like a new instance since the value changes only on a new instance of the gui, but I was wrong. Originally it was only one gui, which is the one on the rightAbsorbed
So assuming for now one GUI, MIS Advanced Computers, what is the computer name JTextField's purpose? Is the user supposed to enter the computer name in it? Or is it to enter text that the search button is supposed find somewhere? Please describe the functionality.Pavo
That is an old label and input field where I originally entered the computer name before I added the second gui to do the same thing. It's old code I haven't removed yet so disregard that.Absorbed
So again, and sorry to beat a horse to death, is your problem one of transferring information from one object to another, from one "gui" to another? If so, don't use text files, but rather simply transfer text. If the smaller window is to act as a modal dialog window, a window that greedily steals all focus from the main window and does not release it until it has completed its functioning, then the solution is simple -- us a modal JDialog for the second window, and when it is finished performing its actions, query the dialog for the information that it holds. If not, use a non-modal JDialog..Pavo
... and some type of listener set up to notify the main GUI when the non-modal dialog's state (its data) has changed, and then have the main GUI query the secondary window for its data.Pavo
The first gui where I enter the partial computer name inputs the partial computer name in this batch file where the %1 is @dsquery computer -name *%1 > resultofbatch.txt and then it outputs to the resultofbatch.txt. Then I'm using bufferedreader to extract in the full computer name. The number one issue is getting the value to update within the same instance of the GUI. Are you saying to use a modal dialog for the tiny gui where I search the computer?Absorbed
Consider instead having the batch file output to the screen, and then you can get the data directly from your process's InputStream. Note that all this running of processes should be done within a background thread such as a SwingWorker.Pavo
I just want to make sure I understand correctly. You are saying to not use buffered reader, but to use inputstream to read the computer name out of the txt file?Absorbed
No, I didn't say not to use a BufferedReader, but rather not to write to and read from a File. Instead you would get your Process's InputStream and ErrorStream, place them in a InputStreamReader, place them into BufferedReaders, and this way get the output of the batch file directly into the calling program.Pavo
Ok. I think I have a good starting point to work from. Thanks for all your help. I've never used inputStreamReader, but I do see some resources on google for using it with command prompt. I've been stuck on this for a couple weeks so I really appreciate all your help. Thanks again!Absorbed
P
3

My recommendations are again that you should:

  • Have your batch file output to the standard output, the console, if you will.
  • Trap that output by capturing the InputStream and the ErrorStream from your Process. These can be trapped together by redirecting the error stream.
  • You should do all of this in a background thread such as with a SwingWorker.
  • I'd make the SwingWorker specifically of type, SwingWorker<Integer, String> so that it can "publish" the Strings read in from its InputStream, and then it can eventually return the process's integer exit code to make sure that the process ran OK.

For instance, say I had a bat file in the user working directory called test.bat that simply printed out the directory of the path passed into it:

test.bat

dir %1

You could call this from a GUI and display the results using the techniques described above.

Note that my code below borrows heavily from MadProgrammer's wonderful answer that can be found here: Printing a Java InputStream from a Process. Please check his answer including his description and up-vote it if it helps you to better understand what's going on.

Also be sure to read Concurrency in Swing for all the details on how to do background threading and in particular SwingWorker use in Swing GUI's.

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;

import javax.swing.*;

@SuppressWarnings("serial")
public class TestBatGui extends JPanel {
   public static final String BATCH_FILE_PATH = "test.bat";
   private JTextArea resultArea = new JTextArea(30, 80);

   public TestBatGui() {
      resultArea.setFocusable(false); // not allow user edits
      resultArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
      JScrollPane scrollPane = new JScrollPane(resultArea);
      scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
      JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      int keyCode = KeyEvent.VK_H;
      String path = System.getProperty("user.home");
      buttonPanel.add(new JButton(new ShowDirAction("Home Dir", keyCode, path)));

      keyCode = KeyEvent.VK_W;
      path = System.getProperty("user.dir");
      buttonPanel.add(new JButton(new ShowDirAction("Working Dir", keyCode,
            path)));

      setLayout(new BorderLayout());
      add(scrollPane, BorderLayout.CENTER);
      add(buttonPanel, BorderLayout.PAGE_END);
   }

   // Action/ActionListener to be used by my buttons
   private class ShowDirAction extends AbstractAction {
      private String path;

      public ShowDirAction(String name, int keyCode, String path) {
         super(name);
         putValue(MNEMONIC_KEY, keyCode);
         this.path = path;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         // our SwingWorker
         BatchFileWorker batchFileWorker = new BatchFileWorker(
               resultArea, BATCH_FILE_PATH, path);
         // add a listener to respond when the worker is done
         batchFileWorker.addPropertyChangeListener(new BatchFileWorkerListener());
         batchFileWorker.execute(); // execute the worker
      }
   }

   // class to listen for when the worker has completed its work
   // and then this class extracts the SwingWorker's results via .get()
   // and does house cleaning if need be.
   private class BatchFileWorkerListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
            BatchFileWorker worker = (BatchFileWorker) evt.getSource();
            try {
               // extract the result returned from the worker's doInBackground() method
               // and most importantly, trap any exceptions thrown
               int exitValue = worker.get();
               String displayText = "";
               if (exitValue != 0) {
                  displayText = String.format("Error when running batch, Exit Value: %d", exitValue);
               } else {
                  displayText = "Batch file ran without error";
               }
               ((Consumer<String>) worker).accept(displayText);
               ((Consumer<String>) worker).accept("\n");
            } catch (InterruptedException e) {
               e.printStackTrace();
            } catch (ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }

   // Our SwingWorker. It's also a Consumer so that outside classes, namely the InputConsumer
   // can pass the strings that it reads back into the worker via the accept(...) method
   private class BatchFileWorker extends SwingWorker<Integer, String> implements Consumer<String> {
      private JTextArea resultArea;
      private String batchFilePath;
      private String dirPath;

      public BatchFileWorker(JTextArea resultArea, String batchFilePath,
            String dirPath) {
         this.resultArea = resultArea;
         this.batchFilePath = batchFilePath;
         this.dirPath = dirPath;
      }

      @Override
      protected Integer doInBackground() throws Exception {
         // command list to load into the process builder
         List<String> commandList = new ArrayList<>();
         int exitCode = 0;
         publish("Getting dir for " + dirPath);
         commandList.add("cmd");
         commandList.add("/c");
         commandList.add(batchFilePath);
         commandList.add(dirPath);

         // create the process builder
         ProcessBuilder pBuilder = new ProcessBuilder(commandList);

         // add the error stream to the input stream so now we have only one stream to handle 
         pBuilder.redirectErrorStream();  
         Process p = pBuilder.start(); // create our process
         InputStream is = p.getInputStream();  // get its InputStream and use it 
         InputStreamReader isr = new InputStreamReader(is);  // to create a 
         BufferedReader br = new BufferedReader(isr);  // BufferedReader
         InputConsumer consumer = new InputConsumer(br, this); // pass into our consumer object
         Thread thread = new Thread(consumer); // start this in a background thread
         thread.start();
         exitCode = p.waitFor(); // wait in this thread for the error code
         thread.join(); // join two threads
         br.close();  // close the BufferedReader
         return exitCode;
      }

      @Override // this allows our InputConsumer to pass Strings read back into the SwingWorker
      public void accept(String text) {
         publish(text);
      }

      @Override // published text will be sent here on the EDT, to be placed into the JTextArea
      protected void process(List<String> chunks) {
         for (String chunk : chunks) {
            resultArea.append(chunk + "\n"); 
         }
      }
   }

   // to read in from the BufferedReader, passing text back into its consumer
   private class InputConsumer implements Runnable {
      private BufferedReader br;
      private Consumer<String> consumer;

      public InputConsumer(BufferedReader br, Consumer<String> consumer) {
         this.br = br;
         this.consumer = consumer;
      }

      @Override
      public void run() {
         String line = null;
         try {
            while ((line = br.readLine()) != null) {
               consumer.accept(line);
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }

   private static void createAndShowGui() {
      TestBatGui mainPanel = new TestBatGui();

      JFrame frame = new JFrame("TestBatGui");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
Pavo answered 12/7, 2015 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.