递归复制文件时使用swingworker

问题描述 投票:0回答:1

递归复制文件时,我无法让 Swingworker 工作。无论我做什么,直到复制所有文件后我的进度条才会更新。我选择做的方向是计算文件总数。然后,我有一个 JLabel,列出了从文件总数中复制的文件数。然后我想要一个进度条来显示复制文件的百分比。

这是我当前的代码(非常基本的应用程序,我知道)

package swingworkertest;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JProgressBar;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.SwingWorker;

public class App extends JFrame {
    private JPanel mainPanel;
    private JButton button;
    private JLabel label;
    private JProgressBar progress;
    
    private int totalFiles = 0;
    private int copiedFiles = 0;
    
    private void getTotalFiles(File src) {
        String[] files = src.list();
        for (int i = 0; i < files.length; i++) {
            if (new File(src + "\\" + files[i]).isDirectory()) {
                getTotalFiles(new File(src + "\\" + files[i]));
            } else {
                totalFiles++;
            }
        }
    }
    
    private void copyFiles(File src, File dst) throws IOException {
        String[] files = src.list();
        
        for (int i = 0; i < files.length; i++) {
            if (new File(src + "\\" + files[i]).isDirectory()) {
                if (Files.notExists(new File(dst + "\\" + files[i]).toPath(), LinkOption.NOFOLLOW_LINKS)) {
                    new File(dst + "\\" + files[i]).mkdir();
                }
                copyFiles(new File(src + "\\" + files[i]), new File(dst + "\\" + files[i]));
            } else {
                Files.copy(new File(src + "\\" + files[i]).toPath(), new File(dst + "\\" + files[i]).toPath());
                copiedFiles++;
                label.setText("Files Copied: " + copiedFiles + "/" + totalFiles);
            }
        }
    }
    
    private void setProgress(int value) {
        progress.setValue(value);
    }
    
    public App(String title) {
        this.setTitle(title);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        String src = "C:\\Users\\Vinny\\Desktop\\workingDirectory";
        String dst = "C:\\Users\\Vinny\\Desktop\\copyToHere";
        
        mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        
        button = new JButton("Copy");
        label = new JLabel("Files Copied: 0/0");
        progress = new JProgressBar();
        progress.setStringPainted(true);
        
        button.addActionListener((e) -> {
            getTotalFiles(new File(src));
            System.out.println(totalFiles);
            SwingWorker<Boolean, Integer> worker = new SwingWorker<>() {
                
                @Override
                protected Boolean doInBackground() throws Exception {
                    // Background Work
                    copyFiles(new File(src), new File(dst));
                    publish(copiedFiles);
                    
                    // Value transmitted to done()
                    return true;
                }
                
                @Override
                protected void process(List<Integer> chunks) {
                    // Process results
                    for (int n : chunks) {
                        int percentage = (int)(n * 100 / totalFiles);
                        setProgress(percentage);
                    }
                }
                
                @Override
                protected void done() {
                    // Finish sequence
                    System.out.println("Files Copied");
                }
            };
            worker.execute();
            
            while (!worker.isDone()) {
                int percentage = (int)(copiedFiles * 100 / totalFiles);
                setProgress(percentage);
            }
        });
        
        
        mainPanel.add(button);
        mainPanel.add(label);
        mainPanel.add(progress);
        
        this.add(mainPanel);
        
        this.pack();
        this.setVisible(true);
    }

}
java swing swingworker filecopy
1个回答
0
投票

这几乎肯定是问题所在。

        worker.execute();
        
        while (!worker.isDone()) {
            int percentage = (int)(copiedFiles * 100 / totalFiles);
            setProgress(percentage);
        }

您正在更新 EDT 的进度。基本上,该循环会占用 UI 线程,而不是让它执行其他工作。如果您希望 EDT 能够实际执行,您必须从后台线程进行更新。

© www.soinside.com 2019 - 2024. All rights reserved.