i am working on a project in java that transfers files from a client to a server. now i need to show the progress bar for each file transfer i.e the progress bar should auto
Check out the ProgressMonitorInputStream
from the Swing tutorial on Using Progress Bars.
Swing is a single threaded framework. That means that all interactions with the UI are expected to be made within the context of this thread (AKA The Event Dispatching Thread).
This also means that if you performing any kind of time consuming/long running or blocking process within the EDT, you will prevent it from responding to events or updating the UI.
This is what your code is currently doing.
There are a number of mechanism available to you to over come this, in your case, the simplest is probably to use a SwingWorker
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
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 class ProgressBar extends JFrame {
JProgressBar current = new JProgressBar(0, 100);
int num = 0;
public ProgressBar() {
//exit button
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create the panel to add the details
JPanel pane = new JPanel();
current.setValue(0);
current.setStringPainted(true);
pane.add(current);
setContentPane(pane);
}
//to iterate so that it looks like progress bar
public void iterate() {
SwingWorker worker = new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
while (num < 2000) {
// current.setValue(num);
try {
Thread.sleep(125);
} catch (InterruptedException e) {
}
num += 95;
int p = Math.round(((float)Math.min(num, 2000) / 2000f) * 100f);
setProgress(p);
}
return null;
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if ("progress".equals(name)) {
SwingWorker worker = (SwingWorker) evt.getSource();
current.setValue(worker.getProgress());
}
}
});
worker.execute();
}
//for testing the app
public static void main(String[] arguments) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
ProgressBar frame = new ProgressBar();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.iterate();
}
});
}
}
Check out http://docs.oracle.com/javase/tutorial/uiswing/concurrency/ for more details.
If you need to display more then one progress bat, you can simply use the publish
and process
methods of SwingWorker
to accomplish more complex results...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
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 class ProgressBar extends JFrame {
JProgressBar current = new JProgressBar(0, 100);
JProgressBar overall = new JProgressBar(0, 100);
int num = 0;
public ProgressBar() {
//exit button
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create the panel to add the details
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
current.setValue(0);
current.setStringPainted(true);
overall.setStringPainted(true);
pane.add(overall, gbc);
pane.add(current, gbc);
setContentPane(pane);
}
//to iterate so that it looks like progress bar
public void iterate() {
SwingWorker worker = new SwingWorker<Object, float[]>() {
@Override
protected void process(List<float[]> chunks) {
float[] progress = chunks.get(chunks.size() - 1); // only want the last one
overall.setValue(Math.round(progress[0] * 100f));
current.setValue(Math.round(progress[1] * 100f));
}
@Override
protected Object doInBackground() throws Exception {
int size = 2000;
int overallSize = size * 10;
int overallProgress = 0;
for (int index = 0; index < 10; index++) {
for (int count = 0; count < size; count++) {
publish(new float[]{
getProgress(overallProgress, overallSize),
getProgress(count, size),
});
overallProgress++;
Thread.sleep(2);
}
}
return null;
}
public float getProgress(int value, int max) {
return (float)value / (float)max;
}
};
worker.execute();
}
//for testing the app
public static void main(String[] arguments) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
ProgressBar frame = new ProgressBar();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.iterate();
}
});
}
}