2009-04-23 10 views
41

मेरे पिछले प्रश्न से संबंधित: Call repaint from another class in Java?मैं जावा में स्विंगवर्कर का उपयोग कैसे करूं?

मैं जावा के लिए नया हूँ, और मैं SwingWorker पर कुछ ट्यूटोरियल पर एक नज़र लिया है, लेकिन मैं अनिश्चित कैसे उदाहरण कोड मैं पिछले प्रश्न में दिया साथ इसे लागू करने के हूँ।

कोई भी बता सकता है कि स्विंगवर्कर का उपयोग मेरे छोटे कोड के संबंध में कैसे करें और मुझे एक सभ्य ट्यूटोरियल की ओर इंगित करें? मैंने देखा है लेकिन मुझे यकीन नहीं है कि मैं अभी तक समझता हूं।

उत्तर

98

आम तौर पर, स्विंगवर्कर का उपयोग स्विंग में लंबे समय तक चलने वाले कार्यों को करने के लिए किया जाता है।

घटना डिस्पैच थ्रेड (EDT) पर लंबे समय से चल चल रहे कार्य जीयूआई तो चीजें हैं जो किया गया था में से एक SwingUtilities.invokeLater उपयोग करने के लिए है और invokeAndWait जो जीयूआई उत्तरदायी रहता है बंद करने के लिए पैदा कर सकता है जो अन्य AWT प्राथमिकता देकर वांछित कार्य (Runnable के रूप में) चलाने से पहले घटनाएं।

हालांकि, SwingUtilities के साथ समस्या यह है कि यह निष्पादित Runnable से मूल विधि में डेटा लौटने की अनुमति नहीं देता है। यह SwingWorker को संबोधित करने के लिए डिज़ाइन किया गया था।

जावा ट्यूटोरियल में SwingWorker पर एक अनुभाग है।

यहां एक उदाहरण है जहां SwingWorker का उपयोग एक अलग थ्रेड पर समय लेने वाले कार्य को निष्पादित करने के लिए किया जाता है, और उत्तर के साथ एक सेकंड बाद एक संदेश बॉक्स प्रदर्शित करता है।

सबसे पहले, एक वर्ग SwingWorker का विस्तार किया जाएगा:

class AnswerWorker extends SwingWorker<Integer, Integer> 
{ 
    protected Integer doInBackground() throws Exception 
    { 
     // Do a time-consuming task. 
     Thread.sleep(1000); 
     return 42; 
    } 

    protected void done() 
    { 
     try 
     { 
      JOptionPane.showMessageDialog(f, get()); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

doInBackground और get तरीकों की वापसी प्रकार SwingWorker के पहले प्रकार के रूप में निर्दिष्ट कर रहे हैं, और दूसरे प्रकार के लिए इस्तेमाल किया प्रकार है publish और process विधियों के लिए वापस आएं, जिनका उपयोग इस उदाहरण में नहीं किया जाता है।

फिर, SwingWorker का आह्वान करने के लिए, execute विधि कहा जाता है। इस उदाहरण में, हम निष्पादित करने के लिए एक JButton के लिए एक ActionListener हुक जाएगा AnswerWorker:

JButton b = new JButton("Answer!"); 
b.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) 
    { 
     new AnswerWorker().execute(); 
    } 
}); 

ऊपर दिए गए बटन एक JFrame में जोड़ा जा सकता है, और पर क्लिक किया एक दूसरे बाद में एक संदेश बॉक्स प्राप्त करने के लिए। निम्नलिखित एक स्विंग आवेदन के लिए जीयूआई प्रारंभ करने में इस्तेमाल किया जा सकता:

private void makeGUI() 
{ 
    final JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    f.getContentPane().setLayout(new FlowLayout()); 

    // include: "class AnswerWorker" code here. 
    // include: "JButton" b code here. 

    f.getContentPane().add(b); 
    f.getContentPane().add(new JButton("Nothing")); 
    f.pack(); 
    f.setVisible(true); 
} 

एक बार आवेदन चलाया जाता है, वहाँ दो बटन हो जाएगा। एक "उत्तर!" लेबल और दूसरा "कुछ भी नहीं"। जब कोई "उत्तर" पर क्लिक करता है बटन, पहले कुछ नहीं होगा, लेकिन "कुछ भी नहीं" बटन पर क्लिक करने से यह काम करेगा और दिखाएगा कि जीयूआई उत्तरदायी है।

और, एक सेकंड बाद, AnswerWorker का परिणाम संदेश बॉक्स में दिखाई देगा।

+0

मुझे विश्वास नहीं है कि मैं जो कर रहा हूं वह एक लंबा चल रहा कार्य है। मैंने इस मुद्दे से निपटने के लिए वैकल्पिक तरीके से सोचा है, और एक और सवाल पूछेगा। धन्यवाद – Relequestual

+3

+1 बहुत बहुत धन्यवाद! :) – coder9

+0

@ कोडर 9 आपका स्वागत है :) – coobird

7

सहमत:

घटना डिस्पैच थ्रेड (EDT) पर लंबे समय से चल चल रहे कार्य जीयूआई बंद हो सकता है।

सहमत नहीं है:

तो

चीजें हैं जो किया गया था से एक का उपयोग करने के लिए है SwingUtilities.invokeLater और invokeAndWait जो जीयूआई उत्तरदायी रहता है ..

invokeLater अभी भी कोड चलाता है ईडीटी पर, और आपके यूआई फ्रीज कर सकते हैं !! इस प्रयास करें:

SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(100000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 

कम से कम मैं अपने माउस को स्थानांतरित नहीं किया जा सकता है एक बार मैं बटन जो ऊपर कोड के साथ actionPerformed से चलाता है पर क्लिक करें। क्या मैं कुछ भूल रहा हूँ?

+0

आप सही हैं। इवेंट प्रेषण धागे पर कुछ चलाने के लिए आम तौर पर invokeLater ईवेंट प्रेषण धागे के बाहर बुलाया जाएगा, उदाहरण के लिए एक लंबे समय तक चलने वाला कार्य प्रदर्शन को बदलने के लिए invokeLater को कॉल कर सकता है। ऐसा इसलिए है क्योंकि स्विंग ऑब्जेक्ट्स पर कार्य थ्रेड सुरक्षा को बनाए रखने के लिए ईवेंट थ्रेड से होना चाहिए। – dhorn

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