我有一个ProgressMonitor pm和一个SwingWorker sw。当我按下cancel上的pm -button时,我想取消SwingWorker。我想这不应该太难,并且我阅读了一些有关SwingWorker和ProgressMonitor的教程,但是我无法使其正常工作。

final ProgressMonitor pm = new ProgressMonitor(frame, "checking", "...", 0, 100);
final SwingWorker sw = new SwingWorker()
{
    protected Object doInBackground() throws Exception
    {
        doSomethingAndUpdateProgress();
    }
};

sw.addPropertyChangeListener(new PropertyChangeListener()
{
    public void propertyChange(PropertyChangeEvent evt)
    {
        if(evt.getPropertyName().equals("progress"))
        {
            updateProgress();
        }
        if(pm.isCanceled())
        {
            cancelAction();
        }
        if(pm.isDone())
        {
            doneAction();
        }
    }
});

sw.execute();

进度更新工作正常,但pm.isCanceled()永远不是true。我想我需要为ProgressMonitor提供一个propertyChangeListener,但是我不知道如何在其中添加一个。

最佳答案

在执行长时间运行的任务期间,您要定期检查ProgressMonitor是否已取消。在需要取消任务的地方进行检查是您的工作,否则谁知道您可以保留哪些资源。

因此,基本上,您想更改doSomethingAndUpdateProgress()方法,以便它也检查ProgressMonitor是否已取消。

这是一个演示如何工作的演示:

import java.awt.*;
import javax.swing.*;

public class TempProject extends Box{

    public TempProject(){
        super(BoxLayout.Y_AXIS);
        final ProgressMonitor pm = new ProgressMonitor(this, "checking", "...", 0, 100);
        final SwingWorker sw = new SwingWorker<Integer, Integer>()
        {
            protected Integer doInBackground() throws Exception
            {
                int i = 0;
                //While still doing work and progress  monitor wasn't canceled
                 while (i++ < 100 && !pm.isCanceled()) {
                     System.out.println(i);
                     publish(i);
                     Thread.sleep(100);
                 }
                 return null;
            }


             @Override
             protected void process(java.util.List<Integer> chunks) {
                 for (int number : chunks) {
                     pm.setProgress(number);
                 }
             }

        };

        sw.execute();
    }


    public static void main(String args[])
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                frame.setContentPane(new TempProject());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }


}

09-26 04:43