0

I needed to add an indeterminant progress bar to an existing Java Swing application that calls a batch job. I needed the progress bar to start running once a Start Job button is clicked but is deleted/disappears once the batch job has completed.
Initially, I had issues with the SwingWorker class but, with the help of examples (see comments) from other users, the code I needed is as follows:

UPDATE/EDIT: Thanks to the comments, the below code does what I need and is a complete (though trivial) application.

NOTE: The batch script in the code (i.e. C:/MyProgress/Test.bat) just sleeps for 20 seconds then exits.

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.IOException;

public class MyProgress extends JPanel
  implements ActionListener {
  private static final long serialVersionUID = 1L;

  JButton bt12, bt13;
  JProgressBar progressBar = new JProgressBar();

  public MyProgress() {

    setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.HORIZONTAL;

    gbc.gridy++;
    gbc.fill = GridBagConstraints.EAST;
    gbc.gridwidth = 1;
    bt12 = new JButton("Start Job");
    bt12.setForeground(Color.GREEN);
    bt12.addActionListener(this);
    add(bt12, gbc);

    gbc.fill = GridBagConstraints.WEST;
    gbc.gridwidth = 2;
    bt13 = new JButton("Exit GUI");
    bt13.setForeground(Color.RED);
    bt13.addActionListener(this);
    add(bt13, gbc);

    gbc.gridy++;
    gbc.fill = GridBagConstraints.CENTER;
    gbc.gridwidth = 10;
    add(progressBar, gbc);

  }   

  public void actionPerformed(ActionEvent e) {

      progressBar.setIndeterminate(true);
      progressBar.setString("Processing ...");
      progressBar.setStringPainted(true);
      progressBar.setForeground(Color.red);

      if (e.getActionCommand().matches("Start Job")) {

        class MyWorker extends SwingWorker<String, Object> {
           protected String doInBackground() {     
             progressBar.setVisible(true); 

             String cmd = "C:/MyProgress/Test.bat";

             Process p = null;
             try {
                p = Runtime.getRuntime().exec(cmd);
             } catch (IOException e) {
                e.printStackTrace();
             }

             try {
               p.waitFor();
             } catch (InterruptedException ite) {
               ite.printStackTrace();
             }

             return "done"; 
             }

           protected void done() {
              progressBar.setVisible(false);
           }  
        } 

        new MyWorker().execute();

      } else if (e.getActionCommand().matches("Exit GUI")) {
             System.exit(0);                                                
      }
  }

  public static void main(String s[]) {

    JFrame frame = new JFrame("MyProgress");
    MyProgress panel = new MyProgress();

    frame.getContentPane().add(panel,"Center");

    frame.addWindowListener(
      new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          System.exit(0);
          }
    });

    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setSize(new Dimension(200, 200)); 
    frame.setLocationRelativeTo(null);          
    frame.setVisible(true);    

   } 
}  
tale852150
  • 1,618
  • 3
  • 17
  • 23
  • ??? The solution **requires** use of a SwingWorker or at least a background thread, but your code shows no attempt with this. You state that you've tried it, but don't show this, and you *will* want to show us this attempt. Else this is a duplicate, and the answer is -- 1) use a SwingWorker. 2) Start the progress bar when and where you call `execute()` on the SwingWorker. 3) Stop the progress bar when the SwingWorker ends. A PropertyChangeListener can help with that, but again if your question is **not** a duplicate, then do please improve it by showing your SwingWorker attempt. – Hovercraft Full Of Eels Apr 29 '17 at 22:22
  • 2
    [For example](http://stackoverflow.com/questions/15801069/printing-a-java-inputstream-from-a-process/15801490#15801490), [example](http://stackoverflow.com/questions/15396694/swing-message-doesnt-get-displayed-until-after-runtime-getruntime-exec-fini/15398441#15398441) and [example](http://stackoverflow.com/questions/15129107/enabling-buttons-while-executing-bat-file/15129240#15129240) - This one includes disabling and reenabling a button – MadProgrammer Apr 29 '17 at 22:24
  • 2
    I'd also encourage you to gave a look at [How to Use CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) – MadProgrammer Apr 29 '17 at 22:24
  • 1
    Also [for example](http://stackoverflow.com/questions/10442406/basic-indeterminate-jprogress-bar-usage) – Hovercraft Full Of Eels Apr 29 '17 at 22:24
  • @Hovercraft Full Of Eels Got it to work and edited question to provide complete, working example. Thanks for all your help. – tale852150 Apr 30 '17 at 04:13
  • Error: you should not make Swing calls from within the doInBackground method – Hovercraft Full Of Eels Apr 30 '17 at 05:10

0 Answers0