How to send console progress information to gui

Discussion in 'Java' started by mike, May 2, 2013.

  1. mike

    mike Guest

    Hi,

    I am using java to send a commdline arg 'mklabel –config hello.o REL3'.
    The output that I get is a new line for each element a put the label on.
    In my application I want to show the user the progress of the command.
    Can I create an event that contains the information for each line and send it to a listener? Or is there a better way?


    br,

    //mike

    Output from console:
    mklabel –config hello.o REL3
    Created label "REL3" on "/usr/hw/" version "/main/1".
    Created label "REL3" on "/usr/hw/src" version "/main/2".
    Created label "REL3" on "/usr/hw/src/hello.c" version "/main/3".
    Created label "REL3" on "/usr/hw/src/hello.h" version "/main/1".
     
    mike, May 2, 2013
    #1
    1. Advertising

  2. mike

    Daniel Pitts Guest

    On 5/2/13 11:49 AM, mike wrote:
    > Hi,
    >
    > I am using java to send a commdline arg 'mklabel –config hello.o REL3'.
    > The output that I get is a new line for each element a put the label on.
    > In my application I want to show the user the progress of the command.
    > Can I create an event that contains the information for each line and send it to a listener? Or is there a better way?
    >
    >
    > br,
    >
    > //mike
    >
    > Output from console:
    > mklabel –config hello.o REL3
    > Created label "REL3" on "/usr/hw/" version "/main/1".
    > Created label "REL3" on "/usr/hw/src" version "/main/2".
    > Created label "REL3" on "/usr/hw/src/hello.c" version "/main/3".
    > Created label "REL3" on "/usr/hw/src/hello.h" version "/main/1".
    >


    You would start a thread to read the data out of the InputStream (which
    you need to do anyway to make a Process work as expected). The thread
    reading the data could send an event anywhere. If you are updating a UI
    thread, I suggest the following approach:

    ProgressTrackerThread.run() will read from InputStream, and when newline
    happens, call "progressUpdated" on a list of Listeners.

    Create an abstract EventQueueProgressListener implementation.
    progressUpdated in this impl will be final, and will pass a Runnable to
    the EventQueue, which then calls a different abstract method
    (handleProgressUpdated maybe?). That way, you're thread-safe on the EDT
    for UI updates.
     
    Daniel Pitts, May 2, 2013
    #2
    1. Advertising

  3. mike

    mike Guest

    On Thursday, May 2, 2013 9:05:08 PM UTC+2, Daniel Pitts wrote:
    > On 5/2/13 11:49 AM, mike wrote:
    >
    > > Hi,

    >
    > >

    >
    > > I am using java to send a commdline arg 'mklabel –config hello.o REL3'.

    >
    > > The output that I get is a new line for each element a put the label on..

    >
    > > In my application I want to show the user the progress of the command.

    >
    > > Can I create an event that contains the information for each line and send it to a listener? Or is there a better way?

    >
    > >

    >
    > >

    >
    > > br,

    >
    > >

    >
    > > //mike

    >
    > >

    >
    > > Output from console:

    >
    > > mklabel –config hello.o REL3

    >
    > > Created label "REL3" on "/usr/hw/" version "/main/1".

    >
    > > Created label "REL3" on "/usr/hw/src" version "/main/2".

    >
    > > Created label "REL3" on "/usr/hw/src/hello.c" version "/main/3".

    >
    > > Created label "REL3" on "/usr/hw/src/hello.h" version "/main/1".

    >
    > >

    >
    >
    >
    > You would start a thread to read the data out of the InputStream (which
    >
    > you need to do anyway to make a Process work as expected). The thread
    >
    > reading the data could send an event anywhere. If you are updating a UI
    >
    > thread, I suggest the following approach:
    >
    >
    >
    > ProgressTrackerThread.run() will read from InputStream, and when newline
    >
    > happens, call "progressUpdated" on a list of Listeners.
    >
    >
    >
    > Create an abstract EventQueueProgressListener implementation.
    >
    > progressUpdated in this impl will be final, and will pass a Runnable to
    >
    > the EventQueue, which then calls a different abstract method
    >
    > (handleProgressUpdated maybe?). That way, you're thread-safe on the EDT
    >
    > for UI updates.



    Thanks for the idea. I appreciate it a lot.

    //mike
     
    mike, May 7, 2013
    #3
  4. mike

    Arne Vajhøj Guest

    On 5/2/2013 2:49 PM, mike wrote:
    > I am using java to send a commdline arg 'mklabel –config hello.o REL3'.
    > The output that I get is a new line for each element a put the label on.
    > In my application I want to show the user the progress of the command.
    > Can I create an event that contains the information for each line and send it to a listener? Or is there a better way?


    Assuming you use Swing for GUI then see the code below for inspiration.

    Arne

    ====

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class CommandOutputDisplay extends JFrame {
    private static final long serialVersionUID = 1L;
    private JTextArea out;
    private JTextArea err;
    private JTextField cmd;
    private JButton exe;
    public CommandOutputDisplay() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().setLayout(new BorderLayout());
    JPanel outerr = new JPanel();
    outerr.setLayout(new GridLayout(1, 2));
    JPanel outwrap = new JPanel();
    outwrap.setLayout(new BorderLayout());
    outwrap.add(new JLabel("Output"), BorderLayout.NORTH);
    out = new JTextArea(20, 80);
    outwrap.add(new JScrollPane(out), BorderLayout.CENTER);
    outerr.add(outwrap);
    JPanel errwrap = new JPanel();
    errwrap.setLayout(new BorderLayout());
    errwrap.add(new JLabel("Error"), BorderLayout.NORTH);
    err = new JTextArea(20, 80);
    errwrap.add(new JScrollPane(err), BorderLayout.CENTER);
    outerr.add(errwrap);
    getContentPane().add(outerr, BorderLayout.CENTER);
    JPanel cmdexe = new JPanel();
    cmdexe.setLayout(new BorderLayout());
    cmdexe.add(new JLabel("Command:"), BorderLayout.WEST);
    cmd = new JTextField("", 80);
    cmdexe.add(cmd, BorderLayout.CENTER);
    exe = new JButton("Execute");
    exe.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    execute();
    }
    });
    cmdexe.add(exe, BorderLayout.EAST);
    getContentPane().add(cmdexe, BorderLayout.SOUTH);
    pack();
    }
    private void execute() {
    try {
    Process p = Runtime.getRuntime().exec(cmd.getText());
    (new GUIReader(p.getInputStream(), out)).start();
    (new GUIReader(p.getErrorStream(), err)).start();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    JFrame f = new CommandOutputDisplay();
    f.setVisible(true);
    }
    });
    }
    }

    class GUIReader extends Thread {
    private BufferedReader br;
    private JTextArea ta;
    public GUIReader(InputStream is, JTextArea ta) {
    this.br = new BufferedReader(new InputStreamReader(is));
    this.ta = ta;
    }
    public void run() {
    String line;
    try {
    while((line = br.readLine()) != null) {
    final String line2 = line;
    EventQueue.invokeLater(new Runnable() {
    public void run() {
    ta.append(line2 + "\r\n");
    }
    });
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
     
    Arne Vajhøj, May 19, 2013
    #4
  5. In article <51981106$0$32109$>,
    Arne Vajhøj <> wrote:

    > On 5/2/2013 2:49 PM, mike wrote:
    > > I am using java to send a commdline arg 'mklabel –config hello.o
    > > REL3'. The output that I get is a new line for each element a put
    > > the label on. In my application I want to show the user the
    > > progress of the command. Can I create an event that contains the
    > > information for each line and send it to a listener? Or is there a
    > > better way?

    >
    > Assuming you use Swing for GUI then see the code below for
    > inspiration.


    [...]

    If I may offer a few enhancements to your excellent sscce, it may be
    convenient to set the default button and focus the text field:

    getRootPane().setDefaultButton(exe);
    cmd.requestFocusInWindow();

    ProcessBuilder allows one to combine the streams and eliminate a pane:

    ProcessBuilder pb = new ProcessBuilder(cmd.getText().split(" "));
    pb.redirectErrorStream();
    Process p = pb.start();
    (new GUIReader(p.getInputStream(), out)).start();

    It may be useful to append diagnostic output in the exception handler:

    StringBuilder sb = new StringBuilder(e.getMessage());
    sb.append(e.getMessage());
    sb.append("\n");
    for (StackTraceElement ste : e.getStackTrace()) {
    sb.append(ste.toString());
    sb.append("\n");
    }
    out.append(sb.toString());

    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
     
    John B. Matthews, May 19, 2013
    #5
  6. On Thursday, May 2, 2013 9:05:08 PM UTC+2, Daniel Pitts wrote:

    > You would start a thread to read the data out of the InputStream (which
    > you need to do anyway to make a Process work as expected). The thread
    > reading the data could send an event anywhere. If you are updating a UI
    > thread, I suggest the following approach:
    >
    > ProgressTrackerThread.run() will read from InputStream, and when newline
    > happens, call "progressUpdated" on a list of Listeners.
    >
    > Create an abstract EventQueueProgressListener implementation.
    > progressUpdated in this impl will be final, and will pass a Runnable to
    > the EventQueue, which then calls a different abstract method
    > (handleProgressUpdated maybe?). That way, you're thread-safe on the EDT
    > for UI updates.


    There is SwingWorker for such things.
    http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

    You still need an additional thread since there are two streams to read from (alternatively use a Selector from NIO).

    Kind regards

    robert
     
    Robert Klemme, May 21, 2013
    #6
  7. On 5/19/2013 12:34 AM, John B. Matthews wrote:
    > In article <51981106$0$32109$>,
    > Arne Vajhøj <> wrote:
    >
    >> On 5/2/2013 2:49 PM, mike wrote:
    >>> I am using java to send a commdline arg 'mklabel –config hello.o
    >>> REL3'. The output that I get is a new line for each element a put
    >>> the label on. In my application I want to show the user the
    >>> progress of the command. Can I create an event that contains the
    >>> information for each line and send it to a listener? Or is there a
    >>> better way?

    >>
    >> Assuming you use Swing for GUI then see the code below for
    >> inspiration.

    >
    > [...]
    >
    > If I may offer a few enhancements to your excellent sscce, it may be
    > convenient to set the default button and focus the text field:
    >
    > getRootPane().setDefaultButton(exe);
    > cmd.requestFocusInWindow();
    >
    > ProcessBuilder allows one to combine the streams and eliminate a pane:
    >
    > ProcessBuilder pb = new ProcessBuilder(cmd.getText().split(" "));
    > pb.redirectErrorStream();
    > Process p = pb.start();
    > (new GUIReader(p.getInputStream(), out)).start();
    >
    > It may be useful to append diagnostic output in the exception handler:
    >
    > StringBuilder sb = new StringBuilder(e.getMessage());
    > sb.append(e.getMessage());
    > sb.append("\n");
    > for (StackTraceElement ste : e.getStackTrace()) {
    > sb.append(ste.toString());
    > sb.append("\n");
    > }
    > out.append(sb.toString());


    I would like to know whether something came from out or err.

    But then I am not a typical GUI user, so you are probably right.

    Arne
     
    Arne Vajhøj, Jun 2, 2013
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Charlie Zhang
    Replies:
    3
    Views:
    1,318
    Paul Lutus
    Aug 16, 2004
  2. Roedy Green
    Replies:
    5
    Views:
    630
    Gordon Beaton
    Jan 30, 2006
  3. Ben Finney
    Replies:
    2
    Views:
    1,019
    Egor Bolonev
    Jun 30, 2003
  4. Egor Bolonev
    Replies:
    0
    Views:
    493
    Egor Bolonev
    Jun 30, 2003
  5. Serge Terekhoff
    Replies:
    0
    Views:
    657
    Serge Terekhoff
    Jun 30, 2003
Loading...

Share This Page