I have a ProgressMonitor pm
and a SwingWorker sw
. I want to cancel the SwingWorker when I press the cancel
-button on pm
. I guess this shouldnt be too hard, and I read some tutorials about SwingWorker and ProgressMonitor, but I can't get this to work.
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();
Progress updating is working just fine, but pm.isCanceled()
is never true
. I suppose I need a propertyChangeListener for the ProgressMonitor, but I dont know how I would add one there.
During the execution of your long running task, you want to periodically check if the ProgressMonitor
was canceled. It's your job to check that at points where it makes sense to cancel the task - otherwise who knows what resources you could leave hanging.
So basically, you want to change your doSomethingAndUpdateProgress()
method so that it also checks if the ProgressMonitor
was canceled.
Here's a demo that shows how this works:
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);
}
});
}
}