I developed a Java application for creating and extracting an archive - like WinRAR. You can create several archives at the same time with multithreading. And recently, I wa
The answer provided by @mKorbel is fine, but there really is no need to use another top-level container (e.g. a JDialog
) to display the progress bar. Instead, you can use the Glass Pane of the JFrame
instance.
Put and display JProgressBar in a JDialog, and don't create a new Top-Level Container. Create that once and re-use that
Long timed and heavy code would be better redirected to the BackGround Task
You can move with progress in JProgressBar
from a background task
only if GUI related code is done on EDT more Concurrency in Swing
and there are two correct ways to do it
by using SwingWorker
from Runnable#Thread
but GUI rellated code must be wrapped into invokeLater()
As suggested by others, the best way is to use SwingWorker
.
SwingWorker
properties are listenable and listeners are always called in the EDT, thus, you could do something like:
public class ArchivingWorker extends SwingWorker<Void, Void> {
JProgressBar progressBar = null;
// Other members here...
...
public ArchivingWorker(...) {
// Any specific initialization here (in EDT)
addPropertyChangeListener(new PropertyChangeListener() {
@Override void propertyChange(PropertyChangeEvent e) {
if ( "state".equals(e.getPropertyName())
&& e.getNewValue() == StateValue.STARTED) {
// Background thread has just started, show a progress dialog here
progressBar = new JProgressBar();
...
}
else if ("progress".equals(e.getPropertyName())) {
// Update progress bar here with e.getNewValue()
...
}
}
});
}
@Override protected Void doInBackground() {
// Archiving process here and update progress from time to time
setProgress(progress);
return null;
}
@Override protected void done() {
// Ensure that archiving process worked correctly (no exception)
try {
get();
} catch (Exception e) {
// Handle exception (user feedback or whatever)
} finally {
// Close progress dialog
...
}
}
}
Then you can use ArchivingWorker
as you need it:
ArchivngWorker worker = new ArchivingWorker(...);
worker.execute();