Nice Looking Progress Bar in Java

Nice looking progress bar in java

If you don't want to replace the user's chosen Look & Feel, you can just replace the UI delegate with one derived from BasicProgressBarUI.

Sample Image

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.plaf.basic.BasicProgressBarUI;

/** @see http://stackoverflow.com/questions/8884297 */
public class ProgressBarUITest extends JPanel {

public ProgressBarUITest() {
JProgressBar jpb = new JProgressBar();
jpb.setUI(new MyProgressUI());
jpb.setForeground(Color.blue);
jpb.setIndeterminate(true);
this.add(jpb);
}

private static class MyProgressUI extends BasicProgressBarUI {

private Rectangle r = new Rectangle();

@Override
protected void paintIndeterminate(Graphics g, JComponent c) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
r = getBox(r);
g.setColor(progressBar.getForeground());
g.fillOval(r.x, r.y, r.width, r.height);
}
}

private void display() {
JFrame f = new JFrame("ProgressBarUITest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new ProgressBarUITest().display();
}
});
}
}

how to make Indeterminate progressbar look nicely?

There's an easier solution. You can just copy the progress bar UI defaults before setting the nimbus look-and-feel and then set them back after. You then get Nimbus look and feel but without its progress bar styling.

// copy progress bar defaults
HashMap<Object, Object> progressDefaults = new HashMap<>();
for(Map.Entry<Object, Object> entry : UIManager.getDefaults().entrySet()){
if(entry.getKey().getClass() == String.class && ((String)entry.getKey()).startsWith("ProgressBar")){
progressDefaults.put(entry.getKey(), entry.getValue());
}
}

// set nimbus
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");

// copy back progress bar defaults
for(Map.Entry<Object, Object> entry : progressDefaults.entrySet()){
UIManager.getDefaults().put(entry.getKey(), entry.getValue());
}

Changing Swing progress bar look and feel

Have you tried setting it to the system's (user's) look and feel?

The easiest way to set the look and feel is by launching the GUI after calling:

try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
// ...
}

With that said, the above appears to be the Windows XP theme and may indeed be the system (user) theme. I generally stay away from custom themes in GUIs unless there is a very good reason (e.g., customer/user requirement).

That is to say, the above code makes it system dependent, which is good because it matches the user's expecations.

How to add a progress bar?

Maybe I can help you with some example code:

public class SwingProgressBarExample extends JPanel {

JProgressBar pbar;

static final int MY_MINIMUM = 0;

static final int MY_MAXIMUM = 100;

public SwingProgressBarExample() {
// initialize Progress Bar
pbar = new JProgressBar();
pbar.setMinimum(MY_MINIMUM);
pbar.setMaximum(MY_MAXIMUM);
// add to JPanel
add(pbar);
}

public void updateBar(int newValue) {
pbar.setValue(newValue);
}

public static void main(String args[]) {

final SwingProgressBarExample it = new SwingProgressBarExample();

JFrame frame = new JFrame("Progress Bar Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(it);
frame.pack();
frame.setVisible(true);

// run a loop to demonstrate raising
for (int i = MY_MINIMUM; i <= MY_MAXIMUM; i++) {
final int percent = i;
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
it.updateBar(percent);
}
});
java.lang.Thread.sleep(100);
} catch (InterruptedException e) {
;
}
}
}
}

Progress Bar Java

You have to use threads for that. Design a class that implements Runnable interface which will update the values like this.

class ProgressBarUpdator implements java.lang.Runnable {

/**
* Progress bar that shows the current status
*/
private javax.swing.JProgressBar jpb = null;
/**
* Progress bar value
*/
private java.lang.Integer value = null;

/**
* Constructor
* @param jpb The progress bar this has to update
*/
public ProgressBarUpdator(javax.swing.JProgressBar jpb) {
this.jpb = jpb;
jpb.setMaximum(100);
}

/**
* Sets the value to the progress bar
* @param value Value to set
*/
public void setValue(java.lang.Integer value) {
this.value = value;
}

/**
* Action of the thread will be executed here. The value of the progress bar will be set here.
*/
public void run() {
do {
if (value != null) {
jpb.setValue((int)java.lang.Math.round(java.lang.Math.floor(value.intValue() * 100 / maximum)));
}
try {
java.lang.Thread.sleep(100L);
} catch (java.lang.InterruptedException ex) {
ex.printStackTrace();
}
} while (value == null || value.intValue() < jpb.getMaximum());
}
}

and in your frame class use progressBar with the new class like this

ProgressBarUpdator ju = new ProgressBarUpdator(progressBar);
new java.lang.Thread(ju).start();

Whenever you want to change the value just use the statement

ju.setValue([Value to set]);

How to make a JProgress bar with a gradient

You'll need a custom ProgressBarUI, perhaps derived from BasicProgressBarUI illustrated here. You may be able to use the existing paintDeterminate() implementation as a guide. A LinearGradientPaint applied to a BasicSliderUI is seen here.

Alternatively, consider the ProgressIcon shown here.

How can I style the ProgressBar component in JavaFX

I have marked this answer as community wiki.

If you have ideas for JavaFX ProgressBar styling outside of the original initial styling queries, please edit this post to add your styling ideas (or to link to them).

set the color of the progress bar itself

Answered in:

  • JavaFX ProgressBar: how to change bar color?

The answer demonstrates

  1. Dynamic styling of the progress bar, so that the bar's color changes depending upon the amount of progress made.
  2. Static styling of the progress bar, which just sets the bar's color forever to a defined color.

JavaFX 7 (caspian) on a Windows PC:

colored progress bar

JavaFX 8 (modena) on a Mac:

progress bar mac

Sometimes people like barbershop pole style gradients, like the bootstrap striped style:

  • ProgressBar Animated Javafx

barbershop quartet

set the background color of the progress bar (not the same as setting the background color)

Define an appropriate css style for the progress bar's "track":

.progress-bar > .track {
-fx-text-box-border: forestgreen;
-fx-control-inner-background: palegreen;
}

progress-bar background color

add a custom text node on top of the progress bar (to show the different states)

Answered in:

  • Draw a String onto a ProgressBar, like JProgressBar?

string on a progress bar

how to change the height of a progress bar:

Answered in:

  • How to get narrow progres bar in JavaFX?

Sample CSS:

.progress-bar .bar { 
-fx-padding: 1px;
-fx-background-insets: 0;
}

José Pereda gives a nice comprehensive solution for narrow progress bars in his answer to:

  • How to get a small ProgressBar in JavaFX

small progress

I am looking for the css class names and the css commands

The place to look is in the default JavaFX style sheet.

  • modena.css for Java 8.
  • caspian.css for Java 7.

The ProgressBar style definitions for caspian (Java 7) are:

.progress-bar {
-fx-skin: "com.sun.javafx.scene.control.skin.ProgressBarSkin";
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-color,30%) 5%, derive(-fx-color,-17%));
-fx-background-insets: 0, 1;
-fx-indeterminate-bar-length: 60;
-fx-indeterminate-bar-escape: true;
-fx-indeterminate-bar-flip: true;
-fx-indeterminate-bar-animation-time: 2;
}

.progress-bar .bar {
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-accent,95%), derive(-fx-accent,10%)),
linear-gradient(to bottom, derive(-fx-accent,38%), -fx-accent);
-fx-background-insets: 0, 1, 2;
-fx-padding: 0.416667em; /* 5 */
}

.progress-bar:indeterminate .bar {
-fx-background-color: linear-gradient(to left, transparent, -fx-accent);
}

.progress-bar .track {
-fx-background-color:
-fx-box-border,
linear-gradient(to bottom, derive(-fx-color,-15%), derive(-fx-color,2.2%) 20%, derive(-fx-color,60%));
-fx-background-insets: 0, 1;
}

.progress-bar:disabled {
-fx-opacity: -fx-disabled-opacity;
}

The progress bar style definitions for modena (Java 8) are:

.progress-bar {
-fx-indeterminate-bar-length: 60;
-fx-indeterminate-bar-escape: true;
-fx-indeterminate-bar-flip: true;
-fx-indeterminate-bar-animation-time: 2;
}
.progress-bar > .bar {
-fx-background-color: linear-gradient(to bottom, derive(-fx-accent, -7%), derive(-fx-accent, 0%), derive(-fx-accent, -3%), derive(-fx-accent, -9%) );
-fx-background-insets: 3 3 4 3;
-fx-background-radius: 2;
-fx-padding: 0.75em;
}
.progress-bar:indeterminate > .bar {
-fx-background-color: linear-gradient(to left, transparent, -fx-accent);
}
.progress-bar > .track {
-fx-background-color:
-fx-shadow-highlight-color,
linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
linear-gradient(to bottom,
derive(-fx-control-inner-background, -7%),
derive(-fx-control-inner-background, 0%),
derive(-fx-control-inner-background, -3%),
derive(-fx-control-inner-background, -9%)
);
-fx-background-insets: 0, 0 0 1 0, 1 1 2 1;
-fx-background-radius: 4, 3, 2; /* 10, 9, 8 */
}

The JavaFX CSS reference guide contains general information on the use of CSS in JavaFX (which differs somewhat from the use of CSS in HTML).

Command line progress bar in Java

I have implemented this sort of thing before. Its not so much about java, but what characters to send to the console.

The key is the difference between \n and \r.
\n goes to the start of a new line. But \r is just carriage return - it goes back to the start of the same line.

So the thing to do is to print your progress bar, for example, by printing the string

"|========        |\r"

On the next tick of the progress bar, overwrite the same line with a longer bar. (because we are using \r, we stay on the same line) For example:

"|=========       |\r"

What you have to remember to do, is when done, if you then just print

"done!\n"

You may still have some garbage from the progress bar on the line. So after you are done with the progress bar, be sure to print enough whitespace to remove it from the line. Such as:

"done             |\n"

Hope that helps.



Related Topics



Leave a reply



Submit