3

I'm trying to run a BASH script inside a shell spawned by Java and then display the results of said BASH script with a JTextArea.

Here is the class where the magic is (supposed to be) happening.

import java.io.IOException;

public class Bobsors {

public static Mainframe frame;

public static void main(String[] args) {

    frame = new Mainframe();
    frame.start();

    run();

}

public static void run() {

    String[] cmd = new String[]{"/bin/sh", "PATH=~/Desktop/bobsors.sh"};
    try {
        Process process = Runtime.getRuntime().exec(cmd);
        frame.setLog(process);
    } catch (IOException e) {
        e.printStackTrace();
    }



}

}

And this is the class for my frame.

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextArea;
import javax.swing.JLabel;
import javax.swing.border.TitledBorder;

@SuppressWarnings("serial")
public class Mainframe extends JFrame {

private JPanel contentPane;

public static Mainframe frame;
public static JTextArea log = new JTextArea();

/**
 * Launch the application.
 */
public void start() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frame = new Mainframe();
                frame.setVisible(true);
                frame.setTitle("Bobsors Java Application.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}



public void setLog(Process process) {
    log.setText(process.toString());
}


/**
 * Create the frame.
 */
public Mainframe() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JPanel panel = new JPanel();
    panel.setBorder(new TitledBorder(null, "Shell Log", TitledBorder.LEADING, TitledBorder.TOP, null, null));
    panel.setBounds(7, 50, 434, 217);
    contentPane.add(panel);
    panel.setLayout(null);

    log.setBounds(5, 17, 424, 210);
    log.setEditable(false);
    panel.add(log);

    JLabel lblBobsors = new JLabel("Bobsors");
    lblBobsors.setBounds(12, 12, 70, 15);
    contentPane.add(lblBobsors);

    JLabel lblWorksOnLinux = new JLabel("Works on Linux only");
    lblWorksOnLinux.setBounds(12, 26, 203, 15);
    contentPane.add(lblWorksOnLinux);


}
}

When running the only thing that gets displayed is this "java.lang.UNIXProcess@509d5bae" Does anyone know how to properly do this?

Vanitas
  • 865
  • 1
  • 7
  • 19
  • 1
    You could having a look at [this example](http://stackoverflow.com/questions/15801069/printing-a-java-inputstream-from-a-process/15801490#15801490) – MadProgrammer Oct 13 '13 at 03:16

2 Answers2

3

Process doesn't override the default toString() method inherited from Object hence why its displaying that value.

Instead you can use getInputStream(), which will return an InputStream object which you can convert to a string like this: Read/convert an InputStream to a String.

Also don't forget tasks on the EDT (event dispatch thread) must finish quickly; if they don't, unhandled events back up and the user interface becomes unresponsive, so make sure you use another thread.

Community
  • 1
  • 1
0x6C38
  • 6,796
  • 4
  • 35
  • 47
0

You can use, InputStream and a BufferedReader to read output, something like this

 InputStream input = process.getInputStream();
 BufferedReader result = new BufferedReader(new InputStreamReader(input));

Convert to String

 StringBuilder builder = new StringBuilder();
 String line="";
 while((line=result.readLine()) != null){
     builder.append(line + "\n");
 }

Please add try & catch appropriately.

lazyprogrammer
  • 633
  • 9
  • 26
  • And now from here on how would I properly display the builder data like a string onto the JTextArea? – Vanitas Oct 13 '13 at 03:49
  • You can use `builder.toString` and then `textArea.setText(stringFromBuilder)`; – lazyprogrammer Oct 13 '13 at 03:51
  • To my surprise after a second run it did work. I have no clue why it didn't work the first time but it does now! Thank you for this answer, I will mark it as answered imideatly. – Vanitas Oct 13 '13 at 03:58
  • 1
    @user2875269: while lazy didn't address this, for god's sake, take care of your threading. If you try to read the BufferedReader on the Swing event thread, you'll freeze your GUI program. I suggest that you accept Mr D's answer rather than this one for this very reason. – Hovercraft Full Of Eels Oct 13 '13 at 04:02
  • At the moment I'm really glad that it works, however I understand why Mr. D's approach is better, I will look into it as soon as I can and if it comforts you accept his answer as the answer. – Vanitas Oct 13 '13 at 04:10
  • No issues man, I myself after reading his entire answer have upvoted it :) – lazyprogrammer Oct 13 '13 at 04:11