2017-09-06 4 views
0

Ich habe die folgende Ausnahme nach dem Abbrechen der SwingWorke Aufgabe gesehen.SwingWorker: Fehler ausgelöst, wenn done() aufgerufen wird, nachdem Worker-Thread abgebrochen wurde

Exception in thread "AWT-EventQueue-0" java.util.concurrent.CancellationException 

Nach der Suche im Netz fand ich below comment from Oracle

Hinweis: Wenn get auf einem Swingworker Objekt nach seinem Hintergrund aufgerufen wird Aufgabe abgebrochen wurde, ist java.util.concurrent.CancellationException geworfen.

Dies ist mein Code, der die Ausnahme generiert.

import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.util.List; 
import java.util.concurrent.ExecutionException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 

public class JasperReportGenerator { 

    private JButton cancel; 
    private JProgressBar pbar; 
    private int count = 0; 
    private JFrame dialog; 

    public JasperReportGenerator() { 
     init(); 
     //Here we do the background task 
     SwingWorker<Boolean, Integer> worker = new SwingWorker<Boolean, Integer>() { 
      @Override 
      protected Boolean doInBackground() throws Exception { 
       for (int i = 0; i < 10; i++) { 
        publish(i * 10); 
        Thread.sleep(1000); 
       } 
       return true; 
      } 

      @Override 
      protected void done() { 
       try { 
        dialog.dispose(); 
        JOptionPane.showMessageDialog(null, "Done", get().toString(), JOptionPane.INFORMATION_MESSAGE); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (ExecutionException ex) { 
        Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 

      @Override 
      protected void process(List<Integer> list) { 
       pbar.setValue(list.get(list.size() - 1)); 
       pbar.setString(list.get(list.size() - 1) + "%"); 
      } 
     }; 
     worker.execute(); 

     //cancel the process 
     cancel.addActionListener((ActionEvent e) -> { 
      worker.cancel(true); 
      dialog.dispose(); 
      System.out.println("bg task cancelled..."); 
     }); 

    } 

    private void init() { 
     dialog = new JFrame("Progress Report"); 
     dialog.setLocationRelativeTo(null); 
     cancel = new JButton("Cancel"); 
     pbar = new JProgressBar(0, 100); 
     pbar.setStringPainted(true); 
     pbar.setIndeterminate(false); 
     dialog.setPreferredSize(new Dimension(400, 250)); 
     dialog.setLayout(new FlowLayout()); 
     dialog.getContentPane().add(pbar); 
     dialog.getContentPane().add(cancel); 
     dialog.pack(); 
     dialog.setVisible(true); 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(() -> { 
      new JasperReportGenerator(); 
     }); 
    } 

} 

ich die Suche nach einer Lösung sah ich this und this aber ich kann nicht fit sie in meinem Fall.

Dies ist, was ich in meinem done() Verfahren getan haben, das Problem

@Override 
     protected void done() { 
      try { 
       if (!isCancelled()) { 
        JOptionPane.showMessageDialog(null, "Done", get().toString(), JOptionPane.INFORMATION_MESSAGE); 
        dialog.dispose(); 
       } 

      } catch (InterruptedException ex) { 
       Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (ExecutionException ex) { 
       Logger.getLogger(JasperReportGenerator.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

Mit meinem done() wie oben entwickelt zu lösen, wird die Ausnahme nicht werfen.

Jetzt würde ich gerne wissen, ob dies eine nice Lösung ist? Was sind die Auswirkungen dieses Codes?

Antwort

1

Ihre Lösung ist nicht perfekt, da zwischen der Zeit, die Sie isCancelled() aufrufen, und der Zeit, die Sie get() aufrufen, eine Annullierung auftreten könnte, was selten zur Ausnahme führen würde. Besser wäre es, die CancellationException abzufangen und damit umzugehen.

+0

Ich hatte das nicht gesehen. Danke für Ihren Vorschlag. – JWizard

Verwandte Themen