我一直在关注这个线程来尝试从我的程序中的一个单独的类更新 JProgressBar:java - Progress Bar - Is it possible to use setProgess() of Progress Bar of the Progress Bar outside the doInBackground() method?
不幸的是,我的代码无法正常工作。我可能错过了一些东西,但我似乎无法弄清楚它是什么。这是我到目前为止写的代码:
这是我用来更新进度条的 propertyChangeListener:
PropertyChangeListener listener = new PropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event){
if("progress".equals(event.getPropertyName())){
progressBar.setValue((int)currentPercent);
progressBar.setString(Integer.toString((int)currentPercent));
}
}
};
SwingWorker 类:
class Task extends SwingWorker<Void, String>{
public Task(){
md = new ManipulateDirectories(this);
}
@Override
public Void doInBackground(){
for(int i = 0; i < directories.length; i++){
md.copyDirectory(directories[i], backupDir);
}
return null;
}
@Override
public void process(List<String> chunks){
}
@Override
public void done(){
closeWindow();
}
public void updateProgress(int tick){
setProgress(tick);
}
}
操作目录类:
public class ManipulateDirectories{
Task task;
public ManipulateDirectories(Task task){
this.task = task;
}
//Recursive function to loop through and copy individual files
public void copyDirectory(File file, File dest){
if(file.isFile()){
try {
FileUtils.copyFileToDirectory(file, dest);
currentSize = currentSize + getDirSize(file);
if(currentSize >= ONE_PERCENT){
currentPercent = currentPercent + (currentSize / ONE_PERCENT);
task.updateProgress((int)currentPercent); //THIS LINE DOES NOT WORK
currentSize = currentSize % ONE_PERCENT;
}
} catch (IOException e) {
e.printStackTrace();
}
} else if (file.isDirectory()){
File newDir = new File(String.format("%s\\%s", dest.getAbsolutePath(), file.getName()));
if(!newDir.exists()){
newDir.mkdir();
for(File f : file.listFiles()){
copyDirectory(f, newDir);
}
}
}
}
public Long getDirSize(File file) {
long size = 0L;
if (file.isFile() && file != null){
size += file.isDirectory() ? getDirSize(file) : file.length();
} else if (file.isDirectory()){
for (File f : file.listFiles()) {
size += f.isDirectory() ? getDirSize(f) : file.length();
}
}
return size;
}
}
如您所见, propertyChangeListener 应该由 swingworker 类中的 updateProgress(int) 方法触发,并且该方法应该由task.updateProgress((int)currentPercent)
ManipulateDirectories 类中的行调用:但是,该行似乎没有调用 updateProgress()。我猜这可能是“任务”的特定实例的问题——也许我正在创建一个没有正确上下文的单独实例?(我知道术语可能有点错误,但希望你能理解我想说的)。谁能发现我的错误?任何帮助将不胜感激,我已经坚持了很长一段时间了。
SSCCE:
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
public class MainClass extends JFrame {
private JProgressBar progressBar;
private DoSomething ds;
private int currentPercent = 0;
private Task task;
private static JPanel contentPane;
private JPanel bottomPane;
private JButton btnCancel;
public static void main(String[] args){
MainClass mc = new MainClass();
mc.createGUI();
}
public void createGUI(){
//Create frame
setTitle("Backup Progress");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 350);
//Create content pane
contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
//Create panel for progress bar/cancel button
bottomPane = new JPanel();
bottomPane.setLayout(new BoxLayout(bottomPane, BoxLayout.Y_AXIS));
progressBar = new JProgressBar(0, 100);
progressBar.setStringPainted(true);
progressBar.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
progressBar.setValue(0);
btnCancel = new JButton("Cancel");
btnCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
closeWindow();
}
});
bottomPane.add(progressBar);
bottomPane.add(btnCancel);
contentPane.add(bottomPane, BorderLayout.SOUTH);
PropertyChangeListener listener = new PropertyChangeListener(){
public void propertyChange(PropertyChangeEvent event){
if("progress".equals(event.getPropertyName())){
progressBar.setValue((int)currentPercent);
progressBar.setString(Integer.toString((int)currentPercent));
}
}
};
setVisible(true);
task = new Task();
task.execute();
}
class Task extends SwingWorker<Void, String>{
public Task(){
ds = new DoSomething(this);
}
@Override
public Void doInBackground(){
for(int i = 0; i < 100; i++){
ds.incrementPercent();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void done(){
closeWindow();
}
public void updateProgress(int tick){
setProgress(currentPercent + tick);
}
}
public class DoSomething{
Task task;
public DoSomething(Task task){
this.task = task;
}
public void incrementPercent(){
task.updateProgress(1);
}
}
public void closeWindow(){
WindowEvent close = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
}
}
我意识到这是一个非常长的 SSCCE,但希望它能够为您提供您需要了解的所有信息。