Home > Software design >  ZIP4J Unzipping/Extraction with ProgressBar / Progress Monitor
ZIP4J Unzipping/Extraction with ProgressBar / Progress Monitor

Time:02-04

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!

CodePudding user response:

I presume you are referring to this screen capture

Refer to the following.

CodePudding user response:

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

  •  Tags:  
  • Related