2012-08-24 12 views
5

Mam ProgressMonitor pm i SwingWorker sw. Chcę anulować SwingWorker po naciśnięciu przycisku cancel-na pm. Myślę, że to nie powinno być zbyt trudne, i czytałem kilka tutoriali o SwingWorker i ProgressMonitor, ale nie mogę tego zrobić.Uzyskiwanie zdarzenia anulowania Java 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(); 

aktualizowanie Progress działa dobrze, ale nigdy nie jest truepm.isCanceled(). Przypuszczam, że potrzebuję właściwości PropertyChangeListener dla ProgressMonitor, ale nie wiem, jak bym ją dodała.

Odpowiedz

4

Podczas wykonywania swojej długiej zadania uruchomionego, chcesz okresowo sprawdzać, czy ProgressMonitor został odwołany. Twoim zadaniem jest sprawdzić, czy w punktach, w których ma sens anulowanie zadania - w przeciwnym razie, kto wie, jakie zasoby możesz pozostawić zawieszone.

Tak więc, zasadniczo, należy zmienić metodę doSomethingAndUpdateProgress(), aby sprawdzała również, czy ProgressMonitor została anulowana.

Oto demo, która pokazuje, jak to działa:

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); 
      } 
     }); 
    } 


} 
+0

odpowiedź allthough mKorbel był bardzo informacyjny, że brakowało ProgressMonitor, o który właściwie pytałem - więc wybrałem to jako odpowiedź. – AntiZamba

4

i przeczytałem kilka tutoriali na temat SwingWorker i ProgressMonitor, ale nie mogę tego uruchomić.

anulowanie zawsze powoływać się 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,V> 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<ArrayList<Integer>, Integer> { 
//The first template argument, in this case, ArrayList<Integer>, 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<Integer> 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<Integer> list = new ArrayList<Integer>(); 
      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<Integer> 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<Integer> 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(); 
      } 
     }); 
    } 
} 
+0

@Andrew Thompson te komentarze są przez 'aterai' lub' darryl' na moje pytanie z 'sun.forum.57' – mKorbel

Powiązane problemy