Swing progress bar (Java) for command tools

I have several C / C ++ command line tools that I wrap Java.Swing as a GUI. Command line tools can take minutes to several hours. A progress bar seems like a good idea to keep users sane. I also think that it would be nice to wrap the GUI for a progress bar and not just use the system. But how?

I think command line tools can write percentages in stderr, and I can somehow read them in java. Not exactly what kind of mechanics it is. I also do not understand asynchronous mapping (learned a little about invokeLater ()). New to Java, and would also appreciate general suggestions. Thanks.

--- update ---

Thank you all for your suggestions. Here is the resulting code.

private void redirectSystemStreams() { OutputStream out_stderr = new OutputStream() { @Override public void write(final int b) throws IOException { update(String.valueOf((char) b)); } @Override public void write(byte[] b, int off, int len) throws IOException { update(new String(b, off, len)); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } }; System.setErr(new PrintStream(out_stderr, true)); } private void update(final String inputText) { int value = 20; //parse inputText; make sure your executable calls fflush(stderr) after each fprintf(). jProgressBar.setValue(value); /* Also one can redirect to a textpane SwingUtilities.invokeLater(new Runnable() { public void run() { //update jTextPane with inputText } }); */ } 
+4
source share
3 answers

It seems very fragile, it would be better to communicate via sockets in a well-established protocol or with some kind of RCP (possibly Google protobuf) or even with webservices.

If you still insist that you can start a Java process with a ProcessBuilder that will give you a Process link to which you can get an InputStream to read the standard output, but again, that seems very fragile to me.

Hope this helps.

+6
source

For the part of fulfilling your problem, you can do something like the following. Note that this is just an example illustrating the point.

Basically, a thread is created to do the job. Presumably, this Runner thread will interact with your C / C ++ code to make it progress. It then invokes the update in the Progress Bars dialog box.

  import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; public class Main { private int value; private Progress pbar; public static void main(String args[]) { new Main(); } public Main() { pbar = new Progress(); Thread t = new Thread(new Runner()); t.start(); } class Progress extends JDialog { JProgressBar pb; JLabel label; public Progress() { super((JFrame) null, "Task In Progress"); pb = new JProgressBar(0, 100); pb.setPreferredSize(new Dimension(175, 20)); pb.setString("Working"); pb.setStringPainted(true); pb.setValue(0); label = new JLabel("Progress: "); JPanel panel = new JPanel(); panel.add(label); panel.add(pb); add(panel, BorderLayout.CENTER); pack(); setVisible(true); } public void update(){ pb.setValue(value); if(value >= 100){ this.setVisible(false); this.dispose(); } } } class Runner implements Runnable { public void run() { for (int i = 0; i <= 100; i++) { value++; pbar.update(); try { Thread.sleep(50); } catch (InterruptedException e) { } } } } } 
+2
source
 // Create a window JFrame frame = new JFrame("Progress"); // Creates a progress bar and add it to the window JProgressBar prog = new JProgressBar(); frame.add(prog); // Run C/C++ application try { Process p = Runtime.getRuntime().exec(new String[]{"filename","arg1","arg2","..."}); // Get InputStream BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); // Update the progress when recieving output from C/C++ new java.util.Timer().schedule(new TimerTask(){ public void run(){ String str = ""; while ((str=br.readLine()!=null) { prog.setValue(new Integer(str)); // Set Value of Progress Bar prog.setString(str+"%"); // Set Value to display (in text) on Progress Bar } } },0,100); // Check every 100 milliseconds // Fit the window to its contents and display it frame.pack(); frame.setVisible(true); } catch (Exception e) { System.out.println("Failed To Launch Program or Failed To Get Input Stream"); } 
+1
source

Source: https://habr.com/ru/post/1347797/


All Articles