Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #23790 > unrolled thread

How to send console progress information to gui

Started bymike <mikaelpetterson@hotmail.com>
First post2013-05-02 11:49 -0700
Last post2013-06-01 22:09 -0400
Articles 7 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  How to send console progress information to gui mike <mikaelpetterson@hotmail.com> - 2013-05-02 11:49 -0700
    Re: How to send console progress information to gui Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2013-05-02 12:05 -0700
      Re: How to send console progress information to gui mike <mikaelpetterson@hotmail.com> - 2013-05-07 04:50 -0700
      Re: How to send console progress information to gui Robert Klemme <shortcutter@googlemail.com> - 2013-05-21 03:22 -0700
    Re: How to send console progress information to gui Arne Vajhøj <arne@vajhoej.dk> - 2013-05-18 19:38 -0400
      Re: How to send console progress information to gui "John B. Matthews" <nospam@nospam.invalid> - 2013-05-19 00:34 -0400
        Re: How to send console progress information to gui Arne Vajhøj <arne@vajhoej.dk> - 2013-06-01 22:09 -0400

#23790 — How to send console progress information to gui

Frommike <mikaelpetterson@hotmail.com>
Date2013-05-02 11:49 -0700
SubjectHow to send console progress information to gui
Message-ID<6aaa6aa4-440f-44fc-8efe-a06f6603e71b@googlegroups.com>
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".

[toc] | [next] | [standalone]


#23791

FromDaniel Pitts <newsgroup.nospam@virtualinfinity.net>
Date2013-05-02 12:05 -0700
Message-ID<ANygt.3001$hl7.91@newsfe14.iad>
In reply to#23790
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.

[toc] | [prev] | [next] | [standalone]


#23885

Frommike <mikaelpetterson@hotmail.com>
Date2013-05-07 04:50 -0700
Message-ID<b85cc46d-ab71-492d-9127-08a1611d51e3@googlegroups.com>
In reply to#23791
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

[toc] | [prev] | [next] | [standalone]


#24144

FromRobert Klemme <shortcutter@googlemail.com>
Date2013-05-21 03:22 -0700
Message-ID<af1c0623-3530-4b7f-bc0a-e0169e4843cb@googlegroups.com>
In reply to#23791
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

[toc] | [prev] | [next] | [standalone]


#24134

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-05-18 19:38 -0400
Message-ID<51981106$0$32109$14726298@news.sunsite.dk>
In reply to#23790
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();
		}
	}
}

[toc] | [prev] | [next] | [standalone]


#24135

From"John B. Matthews" <nospam@nospam.invalid>
Date2013-05-19 00:34 -0400
Message-ID<nospam-13258D.00344119052013@news.aioe.org>
In reply to#24134
In article <51981106$0$32109$14726298@news.sunsite.dk>,
 Arne Vajhøj <arne@vajhoej.dk> 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>

[toc] | [prev] | [next] | [standalone]


#24249

FromArne Vajhøj <arne@vajhoej.dk>
Date2013-06-01 22:09 -0400
Message-ID<51aaa963$0$32115$14726298@news.sunsite.dk>
In reply to#24135
On 5/19/2013 12:34 AM, John B. Matthews wrote:
> In article <51981106$0$32109$14726298@news.sunsite.dk>,
>   Arne Vajhøj <arne@vajhoej.dk> 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web