# CircularProgressBarUI Demo

## What Is It

The `CircularProgressBarUI is a` `javax.swing.plaf.basic.BasicProgressBarUI` that displays the progress of a `JProgressBar` as an arc than starts at the top of a circle and progresses clockwise.

## How To Use It

Simply call:

    progressBar.setUI(new CircularProgressBarUI());

And then you can add any number of additional properties, such as:

    progressBar.putClientProperty(CircularProgressBarUI.PROPERTY_STROKE_WIDTH, 4);
    progressBar.putClientProperty(CircularProgressBarUI.PROPERTY_PULSE_COMPLETION_ACTIVE, true);
    progressBar.putClientProperty(CircularProgressBarUI.PROPERTY_SPARK_ACTIVE, true);
    progressBar.putClientProperty(CircularProgressBarUI.PROPERTY_ACCELERATE, true);
    progressBar.putClientProperty(CircularProgressBarUI.PROPERTY_TRANSITION, true);

## How It Works

This is relatively straight-forward `ProgressBarUI`. It includes support for `JProgressBar` methods like `getPercentComplete()`, `isIndeterminate()`, `isStringPainted()`, `getString()`, `getForeground()`, `getBackground()` and `getFont()`. Also it includes these additional features:

- The stroke width and the font size are automatically calculated based on the size of the JProgressBar. But if you don't like the default stroke width: there is a client property you can set to override it. (See the "Custom Stroke Width" control in this demo.)
- The pulse effect sets off a half-second animation when the progress bar reaches 100%. This helps draw the user's attention to the fact that the progress bar changed from incomplete to complete.
- The transition effect very quickly animates the arc as it increases its value. To see this in action: make sure you've turned off animation in the demo and manually use the "Value" spinner to change the size from 0 to 50.
- The spark effect sets off a small animation every two seconds if the progress bar's value doesn't change. If the user can't see any progress this offers them at least a small assurance that the UI isn't frozen.
- The accelerate effect changes the progress that's rendered (so a value of 50 may be rendered as a value of 25) to help give the illusion that the progress bar accelerates towards the end. This is based on a suggestion from this article:

  > Keep in mind that perception can be just as important as raw speed. In order to make a progress bar feel faster to users you can start the progressive animation slower and allow it to move faster as it approaches the end. This way, you give users a rapid sense of completion time.

## Discussion

There are several great articles further discussing the UX implications of progress feedback. For this project I consulted this one, this one, this one and this one. (And I don't know what to make of this one, but it's very interesting!)

The "indeterminate" property of JProgressBars is a little peculiar. In hindsight: it might have been nice if indeterminate progress bars had been an entirely separate JComponent, because a core part of their data model (the BoundedRangeModel) doesn't make sense when they are indeterminate. (The JThrobber mostly addresses this separation.) But to be fair: JProgressBars have been around since J2SE 1.2, and small (mostly circular) throbbers weren't a phenomenon at that time.

Also remember on Mac you can set the client property "JProgressBar.style" to "circular" on a JProgressBar to get the default Mac throbber.