获取Java ProgressMonitor的取消事件

我有一个ProgressMonitor pm和一个SwingWorker sw 。 我想在pm按下cancel按钮pm取消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() { 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 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); } }); } } 

我读了一些关于SwingWorker和ProgressMonitor的教程,但是我无法让它工作。

取消总是调用InteruptedExeption,

 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; public class SwingWorkerExample extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private final JButton startButton, stopButton; private JScrollPane scrollPane = new JScrollPane(); private JList listBox = null; private DefaultListModel listModel = new DefaultListModel(); private final JProgressBar progressBar; private mySwingWorker swingWorker; public SwingWorkerExample() { super("SwingWorkerExample"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setLayout(new GridLayout(2, 2)); startButton = makeButton("Start"); stopButton = makeButton("Stop"); stopButton.setEnabled(false); progressBar = makeProgressBar(0, 99); listBox = new JList(listModel); scrollPane.setViewportView(listBox); getContentPane().add(scrollPane); //Display the window. pack(); setVisible(true); } //Class SwingWorker T - the result type returned by this SwingWorker's doInBackground //and get methods V - the type used for carrying out intermediate results by this SwingWorker's //publish and process methods private class mySwingWorker extends javax.swing.SwingWorker, Integer> { //The first template argument, in this case, ArrayList, is what s returned by doInBackground(), //and by get(). The second template argument, in this case, Integer, is what is published with the //publish method. It is also the data type which is stored by the java.util.List that is the parameter //for the process method, which recieves the information published by the publish method. @Override protected ArrayList doInBackground() { //Returns items of the type given as the first template argument to the SwingWorker class. if (javax.swing.SwingUtilities.isEventDispatchThread()) { System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() returned true."); } Integer tmpValue = new Integer(1); ArrayList list = new ArrayList(); for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { //find every 100th prime, just to make it slower tmpValue = FindNextPrime(tmpValue.intValue()); //isCancelled() returns true if the cancel() method is invoked on this class. That is the proper way //to stop this thread. See the actionPerformed method. if (isCancelled()) { System.out.println("SwingWorker - isCancelled"); return list; } } //Successive calls to publish are coalesced into a java.util.List, which is what is received by process, //which in this case, isused to update the JProgressBar. Thus, the values passed to publish range from //1 to 100. publish(new Integer(i)); list.add(tmpValue); } return list; }//Note, always use java.util.List here, or it will use the wrong list. @Override protected void process(java.util.List progressList) { //This method is processing a java.util.List of items given as successive arguments to the publish method. //Note that these calls are coalesced into a java.util.List. This list holds items of the type given as the //second template parameter type to SwingWorker. Note that the get method below has nothing to do with the //SwingWorker get method; it is the List's get method. This would be a good place to update a progress bar. if (!javax.swing.SwingUtilities.isEventDispatchThread()) { System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() + returned false."); } Integer percentComplete = progressList.get(progressList.size() - 1); progressBar.setValue(percentComplete.intValue()); } @Override protected void done() { System.out.println("doInBackground is complete"); if (!javax.swing.SwingUtilities.isEventDispatchThread()) { System.out.println("javax.swing.SwingUtilities.isEventDispatchThread() + returned false."); } try { //Here, the SwingWorker's get method returns an item of the same type as specified as the first type parameter //given to the SwingWorker class. ArrayList results = get(); for (Integer i : results) { listModel.addElement(i.toString()); } } catch (Exception e) { System.out.println("Caught an exception: " + e); } startButton(); } boolean IsPrime(int num) { //Checks whether a number is prime int i; for (i = 2; i <= num / 2; i++) { if (num % i == 0) { return false; } } return true; } protected Integer FindNextPrime(int num) { //Returns next prime number from passed arg. do { if (num % 2 == 0) { num++; } else { num += 2; } } while (!IsPrime(num)); return new Integer(num); } } private class TaskListener implements PropertyChangeListener { private String name; TaskListener(String name) { this.name = name; } @Override public void propertyChange(PropertyChangeEvent e) { System.out.println(name + ": " + e.getOldValue() + " -> " + e.getNewValue()); } } private JButton makeButton(String caption) { JButton b = new JButton(caption); b.setActionCommand(caption); b.addActionListener(this); getContentPane().add(b); return b; } private JProgressBar makeProgressBar(int min, int max) { JProgressBar progressBar1 = new JProgressBar(); progressBar1.setMinimum(min); progressBar1.setMaximum(max); progressBar1.setStringPainted(true); progressBar1.setBorderPainted(true); getContentPane().add(progressBar1); return progressBar1; } private void startButton() { startButton.setEnabled(true); stopButton.setEnabled(false); System.out.println("SwingWorker - Done"); } @Override public void actionPerformed(ActionEvent e) { if ("Start" == null ? e.getActionCommand() == null : "Start".equals(e.getActionCommand())) { startButton.setEnabled(false); stopButton.setEnabled(true); // Note that it creates a new instance of the SwingWorker-derived class. Never reuse an old one. (swingWorker = new mySwingWorker()).execute(); // new instance swingWorker.addPropertyChangeListener(new TaskListener("Task")); } else if ("Stop" == null ? e.getActionCommand() == null : "Stop".equals(e.getActionCommand())) { startButton.setEnabled(true); stopButton.setEnabled(false); swingWorker.cancel(true); // causes isCancelled to return true in doInBackground swingWorker = null; } } public static void main(String[] args) { // Notice that it kicks it off on the event-dispatching thread, not the main thread. SwingUtilities.invokeLater(new Runnable() { @Override public void run() { SwingWorkerExample swingWorkerExample = new SwingWorkerExample(); } }); } }