2010-06-03 10 views
5

को साफ़ करने के लिए syncExec और asyncExec को लपेटना मेरे पास टूलकिट के रूप में एसडब्ल्यूटी का उपयोग कर जावा एप्लिकेशन है, और मैं एक जीयूआई तत्व को अपडेट करने के लिए सभी बदसूरत बॉयलर प्लेट कोड से थक गया हूं।जावा एसडब्ल्यूटी: कोड

बस एक विकलांग बटन सेट करने के लिए सक्षम होने के लिए मैं कुछ इस तरह के माध्यम से जाना है:

shell.getDisplay().asyncExec(new Runnable() { 
    public void run() { 
     buttonOk.setEnabled(true); 
    } 
}); 

मैं के रूप में मैं संभवतः कर सकते हैं फ्लैट मेरे स्रोत कोड रखने पसंद करते हैं, लेकिन मैं एक whopping 3 इंडेंटेशन स्तर की जरूरत है बस कुछ आसान करने के लिए।

क्या कोई तरीका है जिससे मैं इसे लपेट सकता हूं? मैं की तरह एक वर्ग चाहते हैं:

public class UIUpdater { 
    public static void updateUI(Shell shell, *function_ptr*) { 
     shell.getDisplay().asyncExec(new Runnable() { 
      public void run() { 
       //Execute function_ptr 
      } 
     }); 
    } 
} 

और इसलिए की तरह इस्तेमाल किया जा सकता है:

UIUpdater.updateUI(shell, buttonOk.setEnabled(true)); 

कुछ इस तरह छुपा भयानक गंदगी SWT सोचने के लिए लगता है कि कुछ भी करने के लिए आवश्यक है के लिए बहुत अच्छा होगा।

जैसा कि मैं इसे समझता हूं, जावा फ़ंक्शन पॉइंटर्स नहीं कर सकता है। लेकिन जावा 7 में कुछ क्लोजर कहा जाएगा जो मुझे चाहिए। लेकिन इस बीच में कुछ भी है जो मैं फ़ंक्शन पॉइंटर या कॉलबैक को निष्पादित करने के लिए किसी अन्य फ़ंक्शन को पास करने के लिए कर सकता हूं?

एक के रूप में अलग रूप में, मुझे लगता है कि करने के लिए यह स्विंग में इस आवेदन को फिर से करना प्रयास के लायक हो जाएगा शुरू कर रहा हूँ, और मैं इस बदसूरत बकवास और SWT की गैर पार platformyness के साथ डाल करने के लिए नहीं है।

+0

मुझे आशा है कि आप जानते हैं, कि स्विंग एकल भी पिरोया है। इसलिए आपको किसी अन्य थ्रेड से जीयूआई तत्व अपडेट करने के लिए SWT में ऐसा करना होगा। केवल अंतर यह है कि जब आप गलत थ्रेड से स्विटिंग विधियों को कॉल करते हैं तो स्विंग अपवाद नहीं फेंकता है। लेकिन जब आप यह गलत करते हैं तो आप अपने ऐप में खराब बुनाई कीड़े देखेंगे। –

उत्तर

4

मुझे अपने एसडब्ल्यूटी कोड में एक ही समस्या थी।

मैंने एक बेस क्लास लिखा था जिसमें asyncExec और syncExec विधियों के अलावा कुछ भी नहीं था। मेरे पास कॉल करने के लिए हर जीयूआई विधि के लिए एक तरीका था।

मेरी गैर-जीयूआई थ्रेड कक्षा ने बेस क्लास को बढ़ाया।

तो गैर जीयूआई धागा कक्षा में, मैं की तरह setEnabled(shell, true)

आधार वर्ग में एक फोन होगा, मैं एक public void setEnabled(Shell shell, boolean flag) विधि है कि अपने पहले उदाहरण में कोड को शामिल किया जाएगा निर्धारित करेंगे।

+0

ऐसा लगता है कि यह फ़ंक्शन पॉइंटर्स और/या क्लोजर के बिना किया जा सकता है। – jonescb

2

मैंने इसे कुछ समय पहले बंद स्रोत प्रोजेक्ट में हल किया था। मेरे एपीआई इस तरह काम किया:

SWTUtils.asyncExec(display).on(this.getClass(), this).runInUIThread(123); 

इस कॉल पैरामीटर 123 साथ उदाहरण this पर विधि runInUIThread(.) चलाना शामिल है। यहां आवश्यक अव्यवस्था पैरामीटर this.getClass() है।

आपका उदाहरण फिर से लिखा:

SWTUtils.asyncExec(shell.getDisplay()).on(Button.class, buttonOk).setEnabled(true); 

मेरे कार्यान्वयन के लिए इस्तेमाल किया CGLib किसी वर्ग के लिए एक गतिशील प्रॉक्सी बनाने के लिए। यह प्रॉक्सी on(.) द्वारा वापस कर दिया गया था, और विधि कॉल और इसके पैरामीटर रिकॉर्ड किए गए थे और display.asyncExec(.) पर पास हुए थे। मैंने प्रॉक्सी के तत्काल के लिए Objenesis का उपयोग किया।

आप आश्चर्यचकित हो सकते हैं कि कोई प्रभावशाली प्रदर्शन प्रभाव नहीं था। चूंकि प्रॉक्सिंग कैश किया गया था और जावा 1.6 में वास्तविक विधि को कॉल करने के लिए आवश्यक प्रतिबिंब एपीआई को इवेंट श्रोताओं के लिए भी इस्तेमाल किया गया था।

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

2

आप कहते हैं कि आप की तरह कुछ हैं:

public class UIUpdater { 
    public static void updateUI(Shell shell, *function_ptr*) { 
     shell.getDisplay().asyncExec(new Runnable() { 
      public void run() { 
       //Execute function_ptr 
      } 
     }); 
    } 
} 

तथ्य यह है कि आप इस SWT के एक समारोह नहीं है नहीं हो सकता है, यह एक प्रोग्रामिंग भाषा के रूप में जावा के एक समारोह है। जावा की उच्च-ऑर्डर फ़ंक्शंस और क्लोजर की कमी आपको एक अच्छा डीएसएल बनाने से रोकती है जो आपके लिए उस क्रूर को छुपाएगी, इसलिए आपके द्वारा प्राप्त किए गए अन्य उत्तरों को तब तक उतना ही अच्छा होगा जब तक आप भाषाएं नहीं बदलते।

अब, यदि आप उदाहरण के लिए स्कैला जैसी भाषा का उपयोग कर रहे थे, तो मुझे लगता है कि उत्तर बहुत अलग है। आप संभवतः एक नियंत्रण संरचना की नकल करने वाले किसी प्रकार का फ़ंक्शन तैयार करेंगे जो सुनिश्चित करेगा कि आपके एसडब्ल्यूटी कॉल मुख्य एसडब्ल्यूटी डिस्प्ले थ्रेड पर निष्पादित किए जाएंगे।

कुछ की तरह:

val enabled = model.isEditable 
Swt { 
    text.setEnabled(enabled); 
    composite.refresh(); 
} 
संबंधित मुद्दे