My question is, how do we achieve putting some progress bar or progress monitoring in unzipping zip file using ZIP4j library and the .extractAll method. I've done a research about this but I did not find any solution for this or maybe I didn't meet the right answer on internet, and I'm here now to ask anyone on how to do it. I'm using GUI Swing framework for testing only. I hope someone can lend their hand answering it. Thank you!
ZIP4J Unzipping/Extraction with ProgressBar / Progress Monitor
550 Views Asked by Scabbard Gaming At
2
There are 2 best solutions below
0
On
To my surprise, Zip4J actually has a reasonable concept of a "progression"!
There's a number of ways you might make this work with Swing, but probably the easiest is to use a SwingWorker, which also has a concept of "progression"
See...
for more details
Runnable example...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.progress.ProgressMonitor;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (ZipException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class TestPane extends JPanel {
private JProgressBar progressBar;
public TestPane() throws ZipException {
progressBar = new JProgressBar();
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
add(progressBar);
ZipFile zipFile = new ZipFile(new File("Test.zip"));
ProgressMonitor monitor = zipFile.getProgressMonitor();
zipFile.setRunInThread(true);
Zip4JZorker worker = new Zip4JZorker(monitor);
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
Object newValue = evt.getNewValue();
System.out.println(propertyName + "/" + newValue);
if ("progress".equals(propertyName) && newValue instanceof Integer) {
int progress = (int) newValue;
progressBar.setValue(progress);
} else if ("state".equals(propertyName) && newValue instanceof SwingWorker.StateValue) {
SwingWorker.StateValue state = (SwingWorker.StateValue) newValue;
if (state == SwingWorker.StateValue.DONE) {
try {
((SwingWorker)evt.getSource()).get();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(TestPane.this, "Operation failed", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}
});
zipFile.addFolder(new File("/some/folder/you/want/zipped"));
worker.execute();
}
}
public class Zip4JZorker extends SwingWorker<Void, Void> {
private ProgressMonitor progressMonitor;
public Zip4JZorker(ProgressMonitor progressMonitor) {
this.progressMonitor = progressMonitor;
}
@Override
protected Void doInBackground() throws Exception {
while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {
//System.out.println("Percentage done: " + progressMonitor.getPercentDone());
//System.out.println("Current file: " + progressMonitor.getFileName());
//System.out.println("Current task: " + progressMonitor.getCurrentTask());
// You could pass on some information to the UI via the
// publish method
setProgress(progressMonitor.getPercentDone());
Thread.sleep(100);
}
// Again, you could pass on additional information to the
// UI via the publish method
if (progressMonitor.getResult().equals(ProgressMonitor.Result.SUCCESS)) {
System.out.println("Successfully added folder to zip");
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.ERROR)) {
throw progressMonitor.getException();
} else if (progressMonitor.getResult().equals(ProgressMonitor.Result.CANCELLED)) {
System.out.println("Task cancelled");
}
return null;
}
}
}
Okay, before anyone asks, what's the difference between this an @Abra's answer, the basic answer is, I use setProgress over publish.
publish can then be used to provide additional details, like the current file being processed. This is just a different way to approach the same problem
I presume you are referring to this Zip4J.
Here is a demo Swing app that hopefully does what you want.
This is how it looks when I run it.
Refer to the following.