Progress Bar Java

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 run method with JProgressBar

Because of the single threaded nature of Swing, you can't perform long running or blocking operations from within the context of the Event Dispatching Thread, nor can you update the UI from outside the context of the Event Dispatching Thread.

See Concurrency in Swing for more details.

Both these things you are taking care of. The problem is, this means that it's possible for the background thread to do more work than is been presented on the UI and there's nothing you can do about. The the best bet is simply trying too keep the UI up-to-date as much as possible

A possible better solution might be to use a SwingWorker, which is designed to make updating the UI easier. See Worker Threads and SwingWorker for more details.

The following example shows a progress bar which will run for 10 seconds with a random delay of up to 500 milliseconds between each update. The progress bar is then update based on the amount of time remaining.

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.time.Duration;
import java.time.Instant;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public final class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

private JProgressBar pb;
private JButton btn;

public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;

btn = new JButton("Go");
pb = new JProgressBar();

add(btn, gbc);
add(pb, gbc);

btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
btn.setEnabled(false);
makeItProgress();
}
});
}

protected void makeItProgress() {
SwingWorker<Double, Double> worker = new SwingWorker<Double, Double>() {
@Override
protected Double doInBackground() throws Exception {
Duration duration = Duration.ofSeconds(10);
Instant startTime = Instant.now();
Duration runningTime = Duration.ZERO;
Random rnd = new Random();
setProgress(0);
do {
Thread.sleep(rnd.nextInt(500));
Instant now = Instant.now();
runningTime = Duration.between(startTime, now);

double progress = (double) runningTime.toMillis() / (double) duration.toMillis();
setProgress((int) (progress * 100));
} while (duration.compareTo(runningTime) >= 0);
setProgress(100);
return 1.0;
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
SwingWorker worker = (SwingWorker) evt.getSource();
if (evt.getPropertyName().equals("progress")) {
int value = (int) evt.getNewValue();
pb.setValue(value);
} else if (evt.getPropertyName().equals("state") && worker.getState() == SwingWorker.StateValue.DONE) {
pb.setValue(100);
btn.setEnabled(true);
}
}
});
worker.execute();
}

}

}

The point of this example is, the progress and the work are mixed into a single operation (the doInBackground method of the SwingWorker) so they are more closely related. The SwingWoker then notifies the PropertyChangeListener of updates, to which it can react to safely on the Event Dispatching Thread

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.

Setting up a progress bar in Java

To begin, your worker is missing some methods it should implement, such as doInBackground() and done(). You also need a constructor to pass Folder[].

public class Combine extends SwingWorker<Integer,Integer>{

Folder[] folders;

public Combine (Folder[] folders)
{ this.folders = folders; }

private void Merge(Folder [])
{ (for int i=0;i<folder.length;i++)
{
merge(folder[i]);
//Send the message of progress here, it will be executed
//from doInBackground()
setProgress(....);
}

}
private void Merge(folder){
output stream;
}

protected Integer doInBackground()
{
merge(folders);
return null;
}

protected void done()
{ .... }
}

Then you would call this worker with

Combine combiner = new Combine(folders);
combiner.execute();

To track progress, this example is from SwingWorker API:

 combiner.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});

Java Progress Bar While Loading From SQL Database

As suggested here, you should retrieve rows in the background using SwingWorker. To see the effect, start from this complete example.

image

  • Add a JProgressBar:

    f.add(model.jpb, BorderLayout.NORTH);

    private static class JDBCModel extends AbstractTableModel {

    private final JProgressBar jpb = new JProgressBar();

    }
  • Set the indeterminate property when the worker thread starts:

    JDBCWorker worker = new JDBCWorker();
    jpb.setIndeterminate(true);
    worker.execute();
  • Clear it in the worker's implementation of done():

    @Override
    protected void done() {
    jpb.setIndeterminate(false);
    }

See this related example if you decide to show intermediate progress.

How to refresh a progress bar in java?

I've stripped out most of the unnecessary code (and fixed your compilation errors), and your example works (I've changed the delay and increment, because again, for reproduction purposes you shouldn't waste people's time)

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;

public class ProgressBar extends JFrame {

private JProgressBar progressBar;

public ProgressBar() {
super("loading");
setSize(200, 100);
Container content = getContentPane();
content.setLayout(new BorderLayout());
progressBar = new JProgressBar();
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setStringPainted(true);
progressBar.setBorder(null);
content.add(progressBar, BorderLayout.SOUTH);
setVisible(true);
}

void updateProgress(final int newValue) {
progressBar.setValue(newValue);
}

public void setValue(final int j) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateProgress(j);
}
});
}

public static void main(final String Args[]) {
ProgressBar myProgressBar = new ProgressBar();
int i = 0;
while (i <= 100) {
System.out.println("" + i + "%");
myProgressBar.setValue(i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
i = i + 5;
}
}
}

You should really have invested the time in creating an SSCCE

Also on a side note, you should follow this advice when handling InterruptedExcetions

Handling ProgressBar in Java Swing

You should really read up on how to do background jobs on Swing. The interface in Swing runs on an Event Dispatch Thread (EDT). The EDT must not stop, or your interface will become unresponsive. But, once you have other threads, only the EDT is allowed to touch interface elements. So this code is a Very Bad Idea, because it makes the interface non-responsive:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
throws InterruptedException {

jProgressBar1.setIndeterminate(true);
Thread.sleep(5000); // <-- interface unresponsive
jProgressBar1.setIndeterminate(false);
Thread.sleep(2000); // <-- interface unresponsive
jProgressBar1.setIndeterminate(true);
Thread.sleep(5000); // <-- interface unresponsive
jProgressBar1.setIndeterminate(false);
}

Instead, you should launch background jobs in a different thread, and let them notify the UI as needed:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
Runnable r = () -> {
signalProgress(true);
Thread.sleep(5000);
signalProgress(false);
Thread.sleep(2000);
signalProgress(true);
Thread.sleep(5000);
signalProgress(false);

};
new Thread(r).start(); // starts a new thread that runs 'r'
}

// this code can be called from any thread
public void signalProgress(final boolean indeterminate) {
// because SwingUtils.invokeLater executes code safely in the EDT
// without invokeLater, the interface state could become corrupted
SwingUtils.invokeLater(() -> jProgressBar.setIndeterminate(indeterminate));
}

Note that there are better ways of doing this. For example, SwingWorker was created to simplify launching background tasks from Swing without messing up the rules of the EDT.



Related Topics



Leave a reply



Submit