我的问题是,在使用zip file库和.extractAll方法解压缩的过程中,如何实现一些进度条或进度监视。我对此做了研究,但我没有找到任何解决办法,或者我在互联网上没有找到正确的答案,我现在在这里询问任何人如何解决这个问题。我只使用GUI Swing框架进行测试。我希望有人能伸出援手回答这个问题。谢谢!
发布于 2022-02-04 11:08:34
我想你指的是这个Zip4J。
这里是一个演示的Swing应用程序,希望能做你想做的事情。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.progress.ProgressMonitor;
public class Zip4jGui implements Runnable {
private JFileChooser fileChooser;
private JFrame frame;
private JProgressBar progressBar;
private JTextField zipFileTextField;
@Override
public void run() {
createAndDisplayGui();
}
private void browseFiles(ActionEvent event) {
if (fileChooser == null) {
fileChooser = new JFileChooser();
}
int choice = fileChooser.showOpenDialog(frame);
if (choice == JFileChooser.APPROVE_OPTION) {
File zipFile = fileChooser.getSelectedFile();
zipFileTextField.setText(zipFile.getAbsolutePath());
}
}
private void createAndDisplayGui() {
frame = new JFrame("Zip4J");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createProgressPanel(), BorderLayout.PAGE_START);
frame.add(createFilePanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
JButton extractButton = new JButton("Extract");
extractButton.addActionListener(this::extractZip);
buttonsPanel.add(extractButton);
return buttonsPanel;
}
private JPanel createFilePanel() {
JPanel filePanel = new JPanel();
JLabel zipFileLabel = new JLabel("ZIP File");
filePanel.add(zipFileLabel);
zipFileTextField = new JTextField(20);
filePanel.add(zipFileTextField);
JButton browseButton = new JButton("Browse...");
browseButton.addActionListener(this::browseFiles);
filePanel.add(browseButton);
return filePanel;
}
private JPanel createProgressPanel() {
JPanel progressPanel = new JPanel();
JLabel progressLabel = new JLabel("Progress");
progressPanel.add(progressLabel);
progressBar = new JProgressBar(0, 100);
progressPanel.add(progressBar);
return progressPanel;
}
private void extractZip(ActionEvent event) {
XtrctTsk task = new XtrctTsk();
task.execute();
}
private class XtrctTsk extends SwingWorker<Void, Integer> {
private ProgressMonitor progressMonitor;
@Override
protected Void doInBackground() throws Exception {
String path = zipFileTextField.getText();
File f = new File(path);
try (ZipFile zipFile = new ZipFile(f)) {
progressMonitor = zipFile.getProgressMonitor();
zipFile.setRunInThread(true);
File dir = f.getParentFile();
zipFile.extractAll(dir.getAbsolutePath());
while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) {
int done = progressMonitor.getPercentDone();
System.out.println("done: " + done);
publish(done);
try {
Thread.sleep(100);
}
catch (InterruptedException xInterrupted) {
// Safe to ignore (I think).
// xInterrupted.printStackTrace();
}
}
}
return null;
}
protected void done() {
progressBar.setValue(100);
JOptionPane.showMessageDialog(frame,
"Extraction ended.",
progressMonitor.getResult().toString(),
JOptionPane.INFORMATION_MESSAGE);
}
protected void process(List<Integer> percents) {
System.out.println("percents = " + percents);
if (percents != null) {
int size = percents.size();
System.out.println("size = " + size);
if (size > 0) {
progressBar.setValue(percents.get(size - 1));
}
}
}
}
public static void main(String[] args) {
Zip4jGui instance = new Zip4jGui();
EventQueue.invokeLater(instance);
}
}这就是我运行它时的样子。

请参阅以下内容。
发布于 2022-02-04 11:19:18
令我惊讶的是,Zip4J实际上有一个合理的“进展”概念!
使用Swing可以通过多种方式使其工作,但最简单的方法可能是使用SwingWorker,它也有一个“进展”的概念
你看..。
了解更多详细信息
可运行的例子。
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;
}
}
}好的,在有人问这个问题之前,@Abra的回答有什么区别,基本的答案是,我使用setProgress而不是publish。
然后,可以使用publish提供其他详细信息,例如正在处理的当前文件。这只是一个不同的方法来处理同样的问题。
https://stackoverflow.com/questions/70983440
复制相似问题