2011-08-25 11 views
51

मेरा प्रश्न SwingUtilities.invokeLater से संबंधित है। मुझे इसका उपयोग कब करना चाहिए? क्या मुझे हर बार जीयूआई घटकों को अद्यतन करने की ज़रूरत है? यह वास्तव में क्या करता है? क्या इसका कोई विकल्प है क्योंकि यह अंतर्ज्ञानी नहीं लगता है और प्रतीत होता है कि अनावश्यक कोड जोड़ता है?SwingUtilities.invokeLater

+2

यह 'Control.BeginInvoke' के बराबर है। – SLaks

+0

@SLaks क्या इसका मतलब है कि अगर मेरे पास एक धागा है तो मुझे इसका उपयोग नहीं करना पड़ेगा? – FadelMS

+4

@FadelMS, चूंकि स्विंग ढांचे के अपने धागे (ईडीटी) के धागे पैदा होते हैं, तो आपके पास हमेशा वह धागा होगा। (* आपके पास "संदेश-जांच" नहीं है - जो उपयोगकर्ता-क्लिक आदि को संसाधित करता है, है ना? तो विभिन्न 'क्रियाप्रवाह' विधियों को कैसे कॉल किया जाता है? ईडीटी द्वारा!) तो जब आप कहते हैं कि आपके पास * एक है * धागा, मुझे यह समझना होगा कि आपके * केवल * में ईडीटी है (यानी, आपने एक जीयूआई फेंक दिया और मुख्य विधि के किनारे से गिर गया)। उस स्थिति में, नहीं, आपको * invokeLater' का उपयोग करने की आवश्यकता नहीं होगी। हालांकि आप किसी भी "पृष्ठभूमि" प्रसंस्करण करने में सक्षम नहीं होंगे। यदि आप करते हैं, तो आप पूरी तरह से जीयूआई लॉक कर देंगे ... – aioobe

उत्तर

52

क्या मुझे हर बार जीयूआई घटकों को अद्यतन करने की आवश्यकता है?

नहीं, आप पहले से ही घटना प्रेषण धागा (EDT) जो हमेशा मामला है जैसे क्लिक और चयन के रूप में उपयोगकर्ता द्वारा आरंभ किए घटनाओं का उत्तर देते समय पर कर रहे हैं। (actionPerformed तरीकों आदि, हमेशा EDT द्वारा कहा जाता है।)

आप EDT तथापि पर नहीं कर रहे हैं और (जीयूआई अपडेट करना चाहते हैं अगर आप कुछ टाइमर धागे से जीयूआई अद्यतन करने के लिए चाहते हैं, या से कुछ नेटवर्क थ्रेड इत्यादि), आपको शेड्यूल ईडीटी द्वारा किए जाने वाले अपडेट के लिए होगा। यही तरीका है कि यह विधि है।

स्विंग मूल रूप से असुरक्षित धागा है। यानी, उस एपीआई के साथ सभी बातचीत को एक थ्रेड (ईडीटी) पर किया जाना चाहिए। यदि आपको किसी अन्य थ्रेड (टाइमर थ्रेड, नेटवर्किंग थ्रेड, ...) से जीयूआई अपडेट करने की आवश्यकता है, तो आपको जिस तरीके का उल्लेख किया गया है उसका उपयोग करने की आवश्यकता है (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...)।

+0

@ जेन्स: जिसका मतलब है कि मैं इसके बिना कर सकता हूं अगर मैं एक ही थ्रेड (स्विंग) पर हूं या रन टाइम पर चीजें कर रहा हूं। – FadelMS

+1

ठीक है, "या रन टाइम पर चीजें करना" बहुत सटीक नहीं है। यदि आप रनटाइम में चीजें करते हैं, तो कहें, टाइमर-थ्रेड, फिर नहीं, आप इस प्रकार के तरीकों के बिना नहीं कर सकते हैं। – aioobe

+0

धन्यवाद एयोबेब, समझ गया। – FadelMS

7

हर घुमाओ आवेदन कम से कम 2 धागे होते हैं:

  1. मुख्य थ्रेड कि आवेदन
  2. EDT (इवेंट थ्रेड भेजने) निष्पादित करता है एक धागा यूआई अपडेट कर देता है (ताकि यूआई स्थिर नहीं होगा)।

यदि आप यूआई अपडेट करना चाहते हैं तो आपको ईडीटी के भीतर कोड निष्पादित करना चाहिए। SwingUtilities.invokeLater जैसे तरीके, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait आपको EDT द्वारा कोड निष्पादित करने की अनुमति देता है।

+0

सरल और समझने में आसान, धन्यवाद – Yahya

3

अधिकांश उपयोगकर्ता द्वारा शुरू की गई घटनाएं (क्लिक, कीबोर्ड) पहले ही ईडीटी पर होंगी, इसलिए आपको इसके लिए स्विंग यूटिलिटीज का उपयोग नहीं करना पड़ेगा। इसमें ईडीटी अपडेट करने वाले आपके मुख्य() थ्रेड और वर्कर थ्रेड को छोड़कर कई मामलों को शामिल किया गया है।

+0

सबसे अधिक नहीं, _all_ – kleopatra

+0

ठीक है, कोई उपयोगकर्ता उस फ़ाइल को अपडेट कर सकता है जिस पर जीयूआई अपडेट करने वाले थ्रेड द्वारा निगरानी की जा रही है। –

+1

हम्म ...जो कि उपयोगकर्ता के द्वारा शुरू की गई घटना (प्रत्यक्ष, जहां वह नियम है) के रूप में गिनती नहीं है: उपयोगकर्ता फ़ाइल (स्विंग के अंदर, ईडीटी पर) अपडेट करता है और इसे सहेजता है (ईडीटी पर एक बटन क्लिक करके), जो ओएस को ट्रिगर करता है फ़ाइल-अपडेट इवेंट (स्विंग के बाहर, ईडीटी से बाहर) अधिसूचना, यह अधिसूचना मॉनिटर (ईडीटी से बाहर) तक पहुंच जाती है जो ईडीटी पर जीयूआई अपडेट करने के लिए ज़िम्मेदार है – kleopatra

7

मेरा प्रश्न इस समय SwingUtilities.invokeLater से संबंधित है: मुझे इसका उपयोग कब करना चाहिए?

समझने की कुंजी क्या है कि जावा के पास स्विंग से संबंधित घटनाओं को संभालने वाला एक अलग थ्रेड (ईडीटी) है।

आपको मौजूदा थ्रेड में इसे करने की कोशिश करने के बजाय, डेस्कटॉप एप्लिकेशन (उदाहरण के लिए) के मुख्य JFrame को प्रदर्शित करने के लिए invokeLater() का उपयोग करना चाहिए। यह बाद में आवेदन के सुंदर समापन के लिए संदर्भ भी बनाएगा।

यह अधिकांश अनुप्रयोगों के लिए है।

क्या मुझे प्रत्येक बार GUI घटकों को अद्यतन करने की आवश्यकता है? यह वास्तव में क्या करता है?

सं।यदि आप एक जीयूआई घटक संशोधित करते हैं, तो यह स्विंग द्वारा बाद में प्रेषण के लिए पंजीकृत एक ईवेंट ट्रिगर करेगा। अगर इस घटना के लिए श्रोता है, तो ईडीटी थ्रेड इसे सड़क के नीचे कहीं भी बुलाएगा। आपको invokeLater() का उपयोग करने की आवश्यकता नहीं है, बस अपने श्रोताओं को घटकों पर सही तरीके से सेट करें।

ध्यान रखें कि यह थ्रेड आपकी स्क्रीन पर एक ही थ्रेड ड्राइंग फ्रेम आदि है ...। इसलिए, श्रोताओं को जटिल/लंबे/सीपीयू गहन कार्यों को नहीं करना चाहिए, अन्यथा आपकी स्क्रीन स्थिर हो जाएगी।

क्या इसका कोई विकल्प है क्योंकि यह अंतर्ज्ञानी नहीं लगता है और प्रतीत होता है कि अनावश्यक कोड जोड़ता है?

आपको invokeLater() + श्रोताओं के साथ अपने आवेदन को प्रदर्शित करने से अधिक कोड लिखने की आवश्यकता नहीं है। शेष स्विंग द्वारा संभाला जाता है।

12
Swing is single threaded and all changes to the GUI must be done on EDT 

बुनियादी उपयोग के लिए invokeLater()

  1. मुख्य तरीकों हमेशा invokeLater() में लिपटे किया जाना चाहिए

  2. देरी से है (लेकिन एसिंक्रोनस रूप से) कार्रवाई/घटना EventQueue के अंत तक,

  3. यदि ईडीटी मौजूद नहीं है तो आपकोका उपयोग कर एक नया ईडीटी बनाना होगा 10। आप के साथ if (SwingUtilities.isEventDispatchThread()) {...

  4. invokeAndWait() मौजूद है यह परीक्षण कर सकते हैं, लेकिन आज तक मैं (सिर्फ मेरे विचार) invokeLater() के बजाय invokeAndWait() का उपयोग कर के लिए एक कारण नहीं मिल रहा है, जीयूआई (JTree & JTable) में कठिन परिवर्तन को छोड़कर, लेकिन सिर्फ साथ Substance L&F

  5. बेसिक सामान (EDT पर घटनाओं के परीक्षण स्थिरता के लिए उत्कृष्ट): Concurrency in Swing

  6. पृष्ठभूमि कार्य से सभी उत्पादन invokeLater()

    में लिपटे किया जाना चाहिए