Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Magic with Merlin: Indeterminate progress bars

A subtle, but important update to JProgressBar

John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.
Author photo
John Zukowski conducts strategic Java consulting with JZ Ventures, Inc., offers technical support through AnswerSquad.com, and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are Mastering Java 2, J2SE 1.4 (Sybex, April 2002) and Learn Java with JBuilder 6 (Apress, March 2002). Reach him at jaz@zukowski.net.

Summary:  Developers use a JProgressBar component to show users how far along a task has progressed. For really long tasks or those where it's difficult to figure out exactly how far along that task is, the Merlin release adds an indeterminate mode to JProgressBar. This month, columnist John Zukowski provides a refresher on using JProgressBar and discusses its new indeterminate mode.

View more content in this series

Date:  18 Nov 2003
Level:  Introductory
Also available in:   Japanese

Activity:  12513 views
Comments:  

Some changes in the Java 2 SDK, Standard Edition, version 1.4 are big, such as the addition of new components like JSpinner, new layout managers like SpringLayout, or new APIs like the Java Logging API. Other changes, such as slight improvements or tweaks to existing APIs, are less dramatic. This month's tip on the JProgressBar component is of the latter variety. It's subtle, but important.

Basic progress bar usage

JProgressBar is part of the original set of Swing components. It offers a simple way to graphically show a process's completion progress. As the process progresses, a bar extends across the component until the job is completed and the bar is filled. The movement of the bar is usually part of some multithreaded task, which helps to avoid blocking progress from the rest of the application, like regular screen updates. While there's no specific rule that says a progress bar must move in linear steps, as a user I would find it a little weird to see the progress move from 10 percent to 35 percent, then back to 27 percent, then up to 80 percent before ending at 0 percent.

You construct a JProgressBar using one of the five constructors, shown in Listing 1:


Listing 1. JProgressBar constructors
  public JProgressBar()
  public JProgressBar(int orientation) 
  public JProgressBar(int minimum, int maximum)
  public JProgressBar(int orientation, int minimum, int maximum)
  public JProgressBar(BoundedRangeModel model)

JProgressBar lets you initialize the orientation and range of values. Orientation is done through the VERTICAL or HORIZONTAL constants of JProgressBar. HORIZONTAL is the default.

After you create the component and show it on the screen, you kick off a secondary thread to perform the task whose progress needs measuring. You then periodically update the current value of the progress bar with the setValue() method to indicate the current progress of the task. Listing 2 shows a simple example of setValue():


Listing 2. Simple JProgressBar usage
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;

public class ProgressSample {
  static class BarThread extends Thread {
    private static int DELAY = 500;
    JProgressBar progressBar;

    public BarThread(JProgressBar bar) {
      progressBar = bar;
    }

    public void run() {
      int minimum = progressBar.getMinimum();
      int maximum = progressBar.getMaximum();
      Runnable runner = new Runnable() {
        public void run() {
          int value = progressBar.getValue();
          progressBar.setValue(value+1);
        }
      };
      for (int i=minimum; i<maximum; i++) {
        try {
          SwingUtilities.invokeAndWait(runner);
          // Our task for each step is to just sleep
          Thread.sleep(DELAY);
        } catch (InterruptedException ignoredException) {
        } catch (InvocationTargetException ignoredException) {
        }
      }
    }
  }
  public static void main(String args[]) {
    // Initialize
    final JProgressBar aJProgressBar = new JProgressBar(0, 100);

    final JButton aJButton = new JButton("Start");

    ActionListener actionListener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        aJButton.setEnabled(false);
        Thread stepper = new BarThread(aJProgressBar);
        stepper.start();
      }
    };

    aJButton.addActionListener(actionListener);

    JFrame theFrame = new JFrame("Progress Bars");
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = theFrame.getContentPane();
    contentPane.add(aJProgressBar, BorderLayout.NORTH);
    contentPane.add(aJButton, BorderLayout.SOUTH);
    theFrame.setSize(300, 100);
    theFrame.show();
  }
}

When you first run this code, you'll see a screen similar to Figure 1.


Figure 1. Starting screen
Starting Screen

You click the button to start the secondary task and update the progress bar as it runs. Figure 2 shows the bar in the middle of its run.


Figure 2. Screen showing progress
Screen Showing Progress

Nothing too fancy going on here. The main code creates the GUI with a button and progress bar. When you select the button, it triggers the action to update the progress bar. The progress bar is meant to measure some task. In the example program, that task is to just sleep for a half second, 100 different times.

By default, there is no graphical indication of progress besides the bar. By adding the line of code shown below, you can have the bar show what percentage of the task is completed as the task progresses:

  aJProgressBar.setStringPainted(true);

Figure 3 shows our screen with the new code added:


Figure 3. Showing completion percentage
Showing Percentage

Indeterminate usage

Starting with the Merlin release, JProgressBar supports yet another mode -- indeterminate. You use this mode for long tasks with no fixed number of steps. It shows constant animation to indicate something is going on, but it doesn't indicate what percentage has completed. If -- or when -- you determine how long a task will take, you can switch back to determinate mode. While in indeterminate mode, though, JProgressBar shows a bar that goes back and forth within the display area.

Listing 3 shows an example of this mode. The new method here is just setIndeterminate(). A value of true means indeterminate, while false is normal or determinate.


Listing 3. Indeterminate progress bars
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ProgressSample2 {
  public static void main(String args[]) {
    final JProgressBar aJProgressBar = new JProgressBar(0, 100);
    aJProgressBar.setIndeterminate(true);

    JButton aJButton = new JButton("Toggle");

    ActionListener actionListener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        boolean indeterminate = aJProgressBar.isIndeterminate();
        aJProgressBar.setIndeterminate(!indeterminate);
      }
    };

    aJButton.addActionListener(actionListener);

    JFrame theFrame = new JFrame("Indeterminate");
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = theFrame.getContentPane();
    contentPane.add(aJProgressBar, BorderLayout.NORTH);
    contentPane.add(aJButton, BorderLayout.SOUTH);
    theFrame.setSize(300, 100);
    theFrame.show();
  }
}

Figure 4 shows the associated screen (you'll have to imagine the bar moving back and forth). The button toggles the progress bar between the indeterminate and determinate modes.


Figure 4. Indeterminate mode
Indeterminate

There are two new UI defaults available to allow you to change the repaint interval and cycle time: ProgressBar.repaintInterval and ProgressBar.cycleTime. Changing these settings -- as shown below -- changes the display speed. The cycle time must be an even multiple of the repaint interval, so if the interval is 100, then the cycle time could be 200, 500, or 1000 -- but not 750.

  UIManager.put("ProgressBar.repaintInterval", new Integer(150));
  UIManager.put("ProgressBar.cycleTime", new Integer(1050));

Note that you need to set these settings before you create the progress bar.


Conclusion

There's much more to the JProgressBar, but none of its other features changed with the 1.4 release. We've simply reviewed the old way of using the component and introduced its new features under Merlin. You might also consider using ProgressMonitor or ProgressMonitorInputStream to monitor the progress of those long tasks. Both take advantage of the JProgressBar internally.


Resources

About the author

Author photo

John Zukowski conducts strategic Java consulting with JZ Ventures, Inc., offers technical support through AnswerSquad.com, and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are Mastering Java 2, J2SE 1.4 (Sybex, April 2002) and Learn Java with JBuilder 6 (Apress, March 2002). Reach him at jaz@zukowski.net.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10887
ArticleTitle=Magic with Merlin: Indeterminate progress bars
publish-date=11182003
author1-email=jaz@zukowski.net
author1-email-cc=jaloi@us.ibm.com