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. Share your thoughts on this article with the author
and other readers in the accompanying discussion
forum. (You can also click Discuss at the
top or bottom of the article to access the forum.)

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
usageJProgressBar 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:

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():

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:

Indeterminate
usageStarting 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.

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.

ConclusionThere'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.