2

このスレッドに従って、プログラム内の別のクラスからJProgressBarを更新しようとしました:

残念ながら、私のコードは正しく動作しません。私はおそらく何かを見逃しましたが、それが何であったかを理解できないようです。これは私がこれまでに書いたコードです:

進行状況バーを更新するために使用する 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);
    }
}

ManipulateDirectories クラス:

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 だと思いますが、知っておく必要のあるすべての情報が得られることを願っています。

4

1 に答える 1

3

リスナーを に追加することはありませんSwingWorker

への変更:

task = new Task();
task.addPropertyChangeListener(listener);

あなたが持っている他のエラーは、 in を決して更新しないということcurrentPercentですupdateProgress

public void updateProgress(int tick){
            currentPercent+=tick;
            setProgress(currentPercent);
}

編集

実際、コード内のエラーは同じです (sscce ではありません) currentPercent。値を更新することはありません。

PropertyChangeListener listener = new PropertyChangeListener(){
            public void propertyChange(PropertyChangeEvent event){
                if("progress".equals(event.getPropertyName())){
                    currentPercent = (int)event.getNewValue();
                    progressBar.setValue(currentPercent);
                    progressBar.setString(Integer.toString(currentPercent));
                }
            }
        };
于 2013-12-28T03:24:54.430 に答える