5

मेरा प्रश्न से निपटने त्रुटि एक सिद्धांत आधारित सवाल है, लेकिन यह मेरे पास है एक विशिष्ट जरूरत को पूरा करता है।SwingWorker में

आप क्या करते हैं जब आपका स्विंगवर्कर एक अपवाद फेंकता है कि आप ए) उम्मीद कर सकते हैं और बी) पुनर्प्राप्त करने और जारी रखने की आवश्यकता है, लेकिन आप उपयोगकर्ता को सूचित करना चाहते हैं कि यह त्रुटि हुई है? आप अपेक्षित अपवाद कैसे प्राप्त करते हैं और उपयोगकर्ता को doInBackground() से नियम नहीं "उल्लंघन का उल्लंघन किए बिना सूचित करते हैं?

मैं कर दिया है, इस समस्या को ध्यान में रखते, एक SSCCE कि मैं इसे नीचे दिए गए प्रश्नों के साथ प्रस्तुत करना चाहते हैं विकसित किया है।

SSCCE:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.concurrent.ExecutionException; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

public class Test { 

    public static void main(String args[]) { 
     final JFrame frame = new JFrame(); 
     JButton go = new JButton("Go."); 
     go.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       new Task(frame); 
      } 
     }); 
     frame.add(go); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    static class Task extends SwingWorker<Void, Void> { 
     JFrame parent; 
     JDialog dialog; 
     public Task(JFrame parent) { 
      this.parent = parent; 
      dialog = new JDialog(parent); 
      JProgressBar jpb = new JProgressBar(); 
      jpb.setIndeterminate(true); 
      dialog.add(jpb); 
      dialog.setLocationRelativeTo(null); 
      dialog.setVisible(true); 
      execute(); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for(int i = 0; i < 100000; i++) { 
       System.out.println(i); 
       try { 
        if(i == 68456) throw new IllegalStateException("Yikes! i = 68456."); 
       } catch (final IllegalStateException e) { 
        SwingUtilities.invokeAndWait(new Runnable() { 
         @Override 
         public void run() { 
          JOptionPane.showMessageDialog(parent, "Error: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 
         } 
        }); 
       } 
      } 
      return null; 
     } 

     @Override 
     protected void done() { 
      if (!isCancelled()) { 
       try { 
        get(); 
       } catch (ExecutionException | InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      System.out.println("done"); 
      dialog.dispose(); 
     } 

    } 
} 

यह doInBackground() विधि के भीतर SwingUtilities.invokeAndWait() कॉल करने के लिए मान्य है? मैं इस पर कुछ थ्रेड रूपरेखा किया था और परिणाम इस प्रकार थे:

enter image description here

एक बार "जाओ" बटन दबाया जाता है, SwingWorker-pool-1-thread-1 धागा ग्रीन चला जाता है। तब, जब अगर स्थिति उत्पन्न होने पर, त्रुटि फेंक दिया जाता है, और त्रुटि संवाद प्रदर्शित किया जाता है, धागा पीला चला जाता है, और वहाँ वास्तव में है एक हरे रंग की AWT-EventQueue-0 धागे पर "ब्लिप", यह दर्शाता है कि EDT लागू किया गया था। मैंने लगभग 10 सेकंड इंतजार किया, "ठीक है," दबाया और SwingWorker थ्रेड फिर से हरा गया।

क्या ऐसा कुछ करने के लिए कोई संभावित नुकसान है? क्या किसी को SwingWorker से वास्तविक समय में गणना त्रुटियों के उपयोगकर्ताओं को सूचित करने का अनुभव है?

मैं ईमानदार रहूंगा, इस दृष्टिकोण ने मुझे लीरी दी है। यह लगता है अपरंपरागत लेकिन मैं निश्चित रूप से यह नहीं कह सकता कि यह एक बुरा विचार है या नहीं।

+0

यदि यह एक संभाला अपवाद आप के बजाय लौटने का कर सकते हैं है '' में Void' doInBackground' कुछ सेम के साथ वापसी '' errorCode' description' .. या अपवाद फोन 'publish' करने के लिए' कहा जाता है और अपवाद संभाल process' हो सकता है जब, या आप 'firePropertyChange' का उपयोग कर सकते हैं कि एक त्रुटि होती है – nachokk

+0

अच्छी तरह से मैं' शून्य 'के अलावा कुछ और वापस कर सकता हूं लेकिन यह मेरा एसएससीसीई है जो' शून्य 'वापस कर रहा है। मेरे वास्तविक आवेदन को अंतरिम परिणाम वापस करने की आवश्यकता हो सकती है। – ryvantage

+0

SwingWorker सही ढंग से doInBackground नहीं किया जाता है, प्रकाशित करने का उपयोग करें (EDT पर किया) JOptionPane, – mKorbel

उत्तर

4

मुझे invokeAndWait() का उपयोग करने में कोई समस्या नहीं है जब उपयोगकर्ता वास्तव में को स्वीकृति देने के लिए की आवश्यकता है। यदि नहीं, जैसा कि example में दिखाया गया है, SwingWorker<Void, String> डेटा और त्रुटि संदेशों को इंटरलेव किए गए publish() पर कॉल कर सकता है। done() में संलग्न एक उपयुक्त संदेश उपयोगकर्ता को आवश्यक होने पर संचित आउटपुट की समीक्षा करने की अनुमति देगा।

संबंधित मुद्दे