3

I have a server call from the UI. It has response time is little high. So I was thinking to display a progress bar during data loading from the server. I have tried the following code using this approach to show the progress bar. Some where I am doing wrong I am not seeing the progress bar when I call the calculateResult() method on button click. I no need to display any percentage on the progress bar. It just needs to show that data is loading.

// The following code I have tried.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

 public class MyProgressBarTest extends JFrame {
private static final long serialVersionUID = 1L;

private static JProgressBar progressBar;

public static void main(String[] args) {
    MyProgressBarTest obj = new MyProgressBarTest();
    obj.createGUI();
}

public void createGUI() {
    JPanel panel = new JPanel();
    JButton button = new JButton("Progress");

    progressBar = new JProgressBar();

    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) {

            MyCustomProgressBarDialog progressBarObj = new    MyCustomProgressBarDialog(progressBar);
            progressBarObj.createProgressUI();

            MyActionPerformer actionObj = new MyActionPerformer(progressBar);
            actionObj.execute();

            progressBarObj.setVisible(false);
        }
    });

//      panel.add(progressBar);
    panel.add(button);
    add(panel);

    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setLocationRelativeTo(null);
//      pack();
    setSize(200, 300);
    setVisible(true);
}
}

class MyActionPerformer extends SwingWorker<String, Object> {

JProgressBar fProgressBar;

public MyActionPerformer(JProgressBar progressBar) {
    this.fProgressBar = progressBar;
    this.fProgressBar.setVisible(true);
    this.fProgressBar.setIndeterminate(true);
}

protected String doInBackground() throws Exception {

    calculateResult();
    return "Finished";
}

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

public void calculateResult() {
    for (int i = 0; i < 500000; i++) {
        System.out.println("Progress Bar: " + i);
    }
}
}

class MyCustomProgressBarDialog extends JDialog {
private static JProgressBar progressBar;

public MyCustomProgressBarDialog(JProgressBar progressBar) {
    this.progressBar = progressBar;
}

public void createProgressUI() {
    add(progressBar);
    setLocationRelativeTo(null);
    setSize(50, 20);
    setVisible(true);
}
}
Community
  • 1
  • 1
Amarnath
  • 8,736
  • 10
  • 54
  • 81
  • You should not interfere with the progress bar in the `doInBackground` method. That method runs in the background (d'oh) and not on the EDT, so you shouldn't modify/access swing components in it. Move those to your constructor or to where you create the `SwingWorker` instance – Robin Nov 13 '12 at 19:17
  • @Robin I ahve edited my code. But my progress dialog is closing before the method is finished. How can I make it wait until the method call finsihes and then close it automatically. – Amarnath Nov 13 '12 at 19:27
  • I added an answer addressing this. Was a bit long to include in a comment – Robin Nov 13 '12 at 19:43

3 Answers3

5

The reason your progress bar disappears immediately is your ActionListener

button.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent arg0) {
   MyCustomProgressBarDialog progressBarObj = new    MyCustomProgressBarDialog(progressBar);
   progressBarObj.createProgressUI();

   MyActionPerformer actionObj = new MyActionPerformer(progressBar);
   actionObj.execute();

   progressBarObj.setVisible(false);
  }
});

The actionObj.execute(); method is not blocking (good thing or it would be useless) meaning that immediately after you start the SwingWorker with that call you will execute the progressBarObj.setVisible(false); statement.

This causes the progress bar dialog to disappear.

I can think of 2 solutions for this

  • Pass the dialog to the SwingWorker as well and call setVisible( false ) on the dialog in the done method of the SwingWorker
  • A SwingWorker fires PropertyChangeEvents which allow you to determine how far it progressed. You can use such a listener to hide the dialog when the calculations are finished
Robin
  • 36,233
  • 5
  • 47
  • 99
  • Thanks :) .. I have done it using the first solution. But which one is actually good to learn .. first one or the second using PropertyChangeEvent? – Amarnath Nov 13 '12 at 20:00
  • 1
    @Che I would say that is a matter of taste. I prefer the first one personally – Robin Nov 13 '12 at 20:55
1

You can't see your progress bar because you are not adding it to your panel

A simple:

panel.add(PROGRESS_BAR);
panel.add(button);

will do the trick.

I hope it helped. Cheers

Bruno Vieira
  • 3,884
  • 1
  • 23
  • 35
1

JProgressBar is a Component. It must be added to a Container in order to be visible. You haven't added yours anywhere.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • +1 .. Yaa .. it worked .. but I need it as a separate frame coming on the top of the main frame. How can I do that .. – Amarnath Nov 13 '12 at 18:55
  • Create a separate JDialog and add the progress bar to it. Be careful at the threading part. – Dan D. Nov 13 '12 at 18:56
  • Thanks for the suggesstion. As you said I have a threading problem now. My progress dialog is closing before my method is finished. I have updated my code – Amarnath Nov 13 '12 at 19:29