Java JProgressBar显示另一个类void的状态

Java JProgressBar显示另一个类void的状态,java,swing,progress,jprogressbar,Java,Swing,Progress,Jprogressbar,我有一个类,它从一个文件夹列表中复制文件,首先以.txt格式加载,然后复制到临时文件夹。我想显示将文件复制到文件夹的进度,反之亦然 这是我的复印课: public class CopyService { private String _destLocation; private List<File> _filePaths = new ArrayList<File>(); private Map<String, String> _fileProperties

我有一个类,它从一个文件夹列表中复制文件,首先以.txt格式加载,然后复制到临时文件夹。我想显示将文件复制到文件夹的进度,反之亦然

这是我的复印课:

public class CopyService {

private String _destLocation;
private List<File> _filePaths = new ArrayList<File>();
private Map<String, String> _fileProperties = new HashMap<String, String>();
private String _rootLocation;

private File _txtFile;

public CopyService() {
setRootLocation(NekretnineService.getRootFolder());
setDestLocation(NekretnineService.getDestFolder());
}

public void copyImagesToTempFolder() throws IOException {
File destLocationFolder = new File(getDestLocation());
if (getFilePaths() != null) {
    if (!destLocationFolder.exists()) {
    destLocationFolder.mkdir();
    }
    for (File f : getFilePaths()) {
    if (f.exists()) {
        FileUtils.copyFileToDirectory(f, destLocationFolder);
    }
    }
}
}

public String getDestLocation() {
return _destLocation;
}

public List<File> getFilePaths() {
return _filePaths;
}

public Map<String, String> getFileProperties() {
return _fileProperties;
}

public String getRootLocation() {
return _rootLocation;
}

public File getTxtFile() {
return _txtFile;
}

public void loadTxtFile(File txtFile) throws Exception {
try {
    int lines = 0;
    List<String> imgNames = new ArrayList<String>();
    try (BufferedReader br = new BufferedReader(new FileReader(txtFile))) {
    String txtLine;
    while ((txtLine = br.readLine()) != null) {
        imgNames.add(txtLine);
        lines++;
    }
    }
    for (String img : imgNames) {
    String fullPath = getRootLocation();
    fullPath += File.separator + img;
    getFilePaths().add(new File(fullPath));
    fullPath = "";
    }
    _fileProperties.put("filename", txtFile.getName());
    _fileProperties.put("filesize", String.valueOf(txtFile.length()));
    _fileProperties.put("totalimgs", String.valueOf(lines));
} catch (Exception e) {
    System.out.println(e.getMessage());
}
}

public void setDestLocation(String destLocation) {
_destLocation = destLocation;
}

public void setFilePaths(List<File> filePaths) {
_filePaths = filePaths;
}

public void setFileProperties(Map<String, String> fileProperties) {
_fileProperties = fileProperties;
}

public void setRootLocation(String rootLocation) {
_rootLocation = rootLocation;
}

public void setTxtFile(File txtFile) {
_txtFile = txtFile;
}

@Override
public String toString() {
return "CopyService [_destLocation=" + _destLocation + ", _filePaths=" + _filePaths + ", _fileProperties="
    + _fileProperties + ", _rootLocation=" + _rootLocation + ", _txtFile=" + _txtFile + "]";
}

我想在进度条上显示复制进度,但我不知道如何实现它,我只知道复制方法与gui在同一个类中。

您希望允许外部类在复制文件时侦听CopyService类状态的更改,但幸运的是Java和Swing有这样的机制,但是学习如何使用这些库需要你付出一些努力。建议:

  • 为CopyService类指定一个SwingPropertyChangeSupport私有实例字段,并初始化实例,传入当前类
    this
    。该对象具有允许其接受侦听器的机制,然后编码人员可以通过调用其方法通知这些侦听器该类中状态的更改
  • 给类a
    public void addPropertyChangeListener(PropertyChangeListener l)
    delegation方法,并在该方法中,将侦听器添加到SwingPropertyChangeSupport实例
  • 给类一个公共常量字符串,比如说
    publicstaticfinalstringcopy=“COPY”
  • 在CopyImageStopTempFolder方法中,增加一个计数器变量,然后通过调用其
    firePropertyChange
    方法通知所有已注册到SwingPropertyChangeSupport实例的侦听器。可以帮助您了解详细信息
  • 通过调用其
    addPropertyChangeListener(…)
    方法并传入有效的PropertyChangeListener,让MainWindow类向其CopyService实例注册一个侦听器(再次检查上面链接的教程)
  • 在这个属性更改侦听器中,获取状态更改信息并使用它更新JProgressBar
  • 重要信息,请在后台线程中调用
    copyImagesToTempFolder(…)
    方法--为此使用SwingWorker,本教程将帮助您:。如果不使用后台线程,那么文件更改过程将阻止Swing事件线程,从而有效地冻结GUI并阻止进度条的运行
另一个更好的选择是让您的CopyService类扩展SwingWorker,然后使用SwingWorker中已经连接的侦听器机制来实现您的目标

例如:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.swing.*;

@SuppressWarnings("serial")
public class ProgressMcve extends JPanel {
    private JProgressBar progressBar = new JProgressBar(0, 100);
    private CopyAction copyAction = new CopyAction();

    public ProgressMcve() {
        progressBar.setStringPainted(true);

        add(progressBar);
        add(new JButton(copyAction));
    }

    private class CopyAction extends AbstractAction {
        public CopyAction() {
            super("Copy");
            putValue(MNEMONIC_KEY, KeyEvent.VK_C);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setEnabled(false);
            progressBar.setValue(0);
            MockCopyService copyService = new MockCopyService();
            copyService.addPropertyChangeListener(new CopyServiceListener());
            copyService.execute();
        }
    }

    private class CopyServiceListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if ("progress".equals(evt.getPropertyName())) {
                int progress = (int) evt.getNewValue();
                progressBar.setValue(progress);
            } else if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
                progressBar.setValue(100);
                progressBar.setString("Done");
                copyAction.setEnabled(true);
                try {
                    ((MockCopyService) evt.getSource()).get();
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void createAndShowGui() {
        ProgressMcve mainPanel = new ProgressMcve();

        JFrame frame = new JFrame("ProgressMcve");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

//模拟类功能的简单MCVE示例类
公共类MockCopyService扩展SwingWorker{
公共静态最终字符串COPY=“COPY”;
private List fileList=new ArrayList();
公共复制服务(){
}
public int getFileListSize(){
//实际回报:
//返回fileList.size();
//模拟报税表:
返回10;
}
public void CopyImageStopTempFolder(){
对于(int i=0;i
1)请参阅,以了解我不再费心解决的问题。2) @JaroslawPawlak是个好主意,还有一个提示:
[mcve]
在注释中自动扩展到。减少输入相同/更多细节。;)3) Java GUI必须在不同的操作系统、屏幕大小、屏幕分辨率等上工作,在不同的地区使用不同的PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或者。。。。以及布局填充和边框。@AndrewThompson谢谢:)谢谢您的解释和帮助,这对我帮助很大!:)
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.swing.*;

@SuppressWarnings("serial")
public class ProgressMcve extends JPanel {
    private JProgressBar progressBar = new JProgressBar(0, 100);
    private CopyAction copyAction = new CopyAction();

    public ProgressMcve() {
        progressBar.setStringPainted(true);

        add(progressBar);
        add(new JButton(copyAction));
    }

    private class CopyAction extends AbstractAction {
        public CopyAction() {
            super("Copy");
            putValue(MNEMONIC_KEY, KeyEvent.VK_C);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setEnabled(false);
            progressBar.setValue(0);
            MockCopyService copyService = new MockCopyService();
            copyService.addPropertyChangeListener(new CopyServiceListener());
            copyService.execute();
        }
    }

    private class CopyServiceListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if ("progress".equals(evt.getPropertyName())) {
                int progress = (int) evt.getNewValue();
                progressBar.setValue(progress);
            } else if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
                progressBar.setValue(100);
                progressBar.setString("Done");
                copyAction.setEnabled(true);
                try {
                    ((MockCopyService) evt.getSource()).get();
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void createAndShowGui() {
        ProgressMcve mainPanel = new ProgressMcve();

        JFrame frame = new JFrame("ProgressMcve");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
// simple MCVE example class that mocks the functioning of your class
public class MockCopyService extends SwingWorker<Void, Integer> {
    public static final String COPY = "copy";
    private List<File> fileList = new ArrayList<>();

    public MockCopyService() {

    }

    public int getFileListSize() {
        // the real return:
        // return fileList.size();

        // the mock return:
        return 10;
    }

    public void copyImagesToTempFolder() {
        for (int i = 0; i < getFileListSize(); i++) {
            System.out.println("copying file");
            int fileProgress = (100 * i) / getFileListSize();
            // notify listeners
            setProgress(fileProgress);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        setProgress(getFileListSize());
    }

    @Override
    protected Void doInBackground() throws Exception {
        copyImagesToTempFolder();
        return null;
    }
}