2009-01-23 9 views
8

एक जावा स्विंग अनुप्रयोग में एक मेनू के निर्माण के लेखन के अनुभवहीन रास्ता की तरह कुछ करने के लिए है:सही तरीका जावा में मेनू, टूलबार, और अन्य घटकों को बनाने के लिए कार्रवाई का उपयोग करने के

JMenu fileMenu = new JMenu("File"); 
JMenuItem openItem = new JMenuItem("Open..."); 
openItem.addActionListener(new ActionListener() { /* action listener stuff */ }) 
fileMenu.addMenuItem(openItem); 

एक अधिक अनुभवी डेवलपर होगा पहचानें कि विभिन्न तंत्रों के माध्यम से क्रियाओं का उपयोग किया जा सकता है - मेनू, टूलबार बटन, शायद सिस्टम में अन्य वर्कफ़्लो भी।

Action openAction = new AbstractAction(); 
openAction.setName("Open..."); 
openAction.addActionListener(new ActionListener() { /* action listener stuff */ }) 
... 
JMenuItem openItem = new JMenuItem(openAction); 

मेरा प्रश्न, इन कार्रवाई तो वे मेनू, उपकरण पट्टियों भर में इस्तेमाल किया जा सकता वस्तुओं, आदि का प्रबंधन करने के लिए सबसे अच्छा तरीका क्या है: वह व्यक्ति अधिक लिखने की संभावना है?

  • एक कारखाना वर्ग बनाएं जो विशिष्ट कार्यवाही करता है?
  • कुछ उपयोगिता वर्ग में private static final Action के रूप में सभी कार्यों को घोषित करें?
  • जावा एप्लिकेशन ढांचे का लाभ उठाएं?
  • कुछ और? एक ActionListener एक गरीब आदमी का Map को वेल्डेड -
+0

डेव रे द्वारा बताए गए अनुसार http://stackoverflow.com/questions/448179/organizing-actions-in-a-swing-application#448195 का डुप्लिकेट। –

उत्तर

4

जो अनुप्रयोग मैंने विकसित किए हैं, उन्हें मेनू, टूलबार और अन्य बटनों में उसी क्रिया का उपयोग करने की आवश्यकता है स्विंग एप्लिकेशन फ्रेमवर्क का उपयोग करके किया गया है।

Swing Application Framework

इस ढांचे आप संसाधन फ़ाइल जहां आप सभी मेनू पाठ, टूलटिप्स, और चिह्न परिभाषित कर सकते हैं करने के लिए अनुमति देगा। मुझे लगता है कि आइकन कुंजी हैं, आपको उन्हें स्वयं लोड नहीं करना है। साथ ही, यदि आपके पास कोई भी क्रिया है जिसे आपको सक्षम/अक्षम करने की आवश्यकता है तो आप अपने राज्य को नियंत्रित करने के लिए विधि को ओवरराइड कर सकते हैं।

वेबसाइट पढ़ने योग्य है।

0

Action एक बुरा अमूर्त है।

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

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

1

आप समर्पित नक्शा javax.swing.actionmap का उपयोग कर अपने सभी अमूर्त क्रिया को समूहित कर सकते हैं। http://java.sun.com/javase/6/docs/api/javax/swing/ActionMap.html

इसके अलावा प्रत्येक जेकंपोनेंट में एक आंतरिक actionMap (getActionMap()) है।

class MyComponent 
extends JPanel 
{ 
public static final String ACTION_NAME1="my.action.1"; 

public MyComponent() 
{ 
AbstractAction action= new AbstractAction() { ... } 
getActionMap().put(ACTION_NAME1,action); 
... 

menu.add(getActionMap().get(ACTION_NAME1)); 
} 

} 

आशा है कि यह

0

में मदद करता है इसके अलावा this question है, जो काफी है कि तुम क्या कह रहे हैं के रूप में ही है देखते हैं।

0

संपादित करें: मुझे लगता है कि लोगों को यह विश्वास नहीं हुआ कि यह संभव था या आसान था, इसलिए मैंने इसे किया - स्क्रैच से लगभग एक घंटे लग गए - अगर मैं एक विधि का उपयोग करता तो 40 मिनट लेता प्रत्येक मेनू आइटम के लिए अलग-अलग विधियों को प्रतिबिंबित करने के बजाय एक लक्ष्य।

यहां Tested source code है। यह काम करता है, लेकिन एक बड़ी विधि और बदसूरत है - अगर आप इसे इस्तेमाल करते हैं तो इसे दोबारा दोहराएं। मैं इसे अगले कुछ दिनों में थोड़ा सा ठीक कर सकता हूं, मैं हमेशा इस पर एक प्रतिलिपि रखना चाहता हूं ताकि पुन: उपयोग किया जा सके।

--- मूल पोस्ट

सबसे पहले, डेटा से अपने कोड को अलग करने याद है। इसका मतलब है कि आपको कभी भी टाइप नहीं करना चाहिए:

new Menu("File..."); 

स्ट्रिंग "फ़ाइल ..." डेटा है। यदि आप इस तरह से सोचना शुरू करते हैं, तो आप पाएंगे कि आपका प्रश्न स्वयं उत्तर देता है।

सबसे पहले आपको कुछ डेटा बनाने की आवश्यकता है। आपको मेनू में "फ़ाइल ..." और "सहेजें" प्राप्त करने की आवश्यकता है। मैं आम तौर पर एक स्ट्रिंग सरणी (जो आप आसानी से एक फाइल करने के लिए स्थानांतरित कर सकते हैं)

new String[]{"File...","+Save","Load"...} 

यह सरल पैटर्न मैं के साथ बाहर शुरू कर दिया है में से एक है के साथ शुरू। फिर आप + चिह्न को पार्स कर सकते हैं और इसका मतलब यह है कि "इसे जोड़ने के दौरान मेनू में एक स्तर ड्रॉप करें"

यह सिर्फ एक मूर्खतापूर्ण सम्मेलन है, अगर आप इसे पसंद नहीं करते हैं तो अपना खुद का आविष्कार करें।

अगला चरण बाध्यकारी है कि कोड चलाने के लिए बाध्यकारी है। आप उन्हें सभी एक ही विधि कह सकते हैं, लेकिन गधे में क्या दर्द (विशाल स्विच स्टेटमेंट)। डेटा में पढ़ने के दौरान एक विधि नाम बांधने के लिए प्रतिबिंब का उपयोग करना एक संभावना है। यहाँ एक समाधान है (फिर से यह अपने स्वाद फिट नहीं हो सकता है)

new String[]{"File...[fileMenu]","+Save[saveMenu]","Load[loadMenu]"...} 

तो फिर तुम वर्ग कोष्ठकों में बात पार्स आउट, संजीदगी से अपने वर्तमान कक्षा में एक विधि के लिए इसे हुक और आप सेट कर रहे हैं।

इस समय एक प्रलोभन है जो मैंने हमेशा किया है, और मैंने इसे लड़ना सीखा है क्योंकि यह कभी काम नहीं करता है। प्रलोभन डेटा के पहले सेट ("फ़ाइल ...") का उपयोग करना है और इसे कुछ पैटर्न फिट करने के लिए कुशलतापूर्वक उपयोग करना है और स्वचालित रूप से अपने कोड से बांधना है (इस मामले में, सभी गैर-अल्फा वर्णों को हटाएं, पहला अक्षर कम केस बनाएं और सही विधि नाम प्राप्त करने के लिए "मेनू" संलग्न करें)। इसे आज़माने के लिए स्वतंत्र महसूस करें, यह बहुत आकर्षक है और लगता है कि यह चिकना लगता है, लेकिन इसे छोड़ने के लिए तैयार रहें जब यह कुछ ज़रूरतों को पूरा नहीं करता है (जैसे विभिन्न मेनू में सटीक समान नाम वाले दो मेनू आइटम)।

एक और तरीका है अपनी भाषा बंद का समर्थन करता है, तो आप वास्तव में एक ही स्थान पर फ़ाइल नाम और बंद ..

वैसे भी बना सकते हैं, एक बार आप इस तरह कोडिंग शुरू करते हैं, आपको लगता है कि मिल जाएगा होगा सभी अपने मेनू निर्माण एक एकल 10 लाइन विधि में है और आप इसे अपनी आवश्यकताओं के अनुसार बदल सकते हैं। मेरे पास एक मामला था जहां मुझे मेनू के एक सेट को एक पदानुक्रम में बदलना पड़ा और मैंने इसे 2 मिनट में किया।

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

यह वास्तव में मुश्किल नहीं है कोड है, एक या दो घंटे की तरह लेना चाहिए तो आप नए मेनू लिखने के लिए की आवश्यकता नहीं है ("... फिर से। मुझ पर विश्वास करो, टूलींग इस तरह की बस के बारे में हमेशा इसके लायक है।

संपादित करें:

मैं बस के बारे में हमेशा कोड डेटा के आधार पर इन दिनों आम तौर पर मैं कुछ चीजें सामान्य तरीके प्रोटोटाइप होगा, पैटर्न और refactor पहचान - डेटा बस के बारे में हमेशा और आप सही तरीके से पुनर्रचना कर रहे हैं,। कारक बाहर और जो आपने छोड़ा है वह सुंदर, तंग और रखरखाव योग्य है।

मैं 1/2 से कम में ऊपर सुझाए गए सुझावों को कर सकता हूं हमारा (शायद प्रतिबिंबित संस्करण करने के लिए एक घंटा)। यह लगभग हमेशा तब तक होता है जब तक कि यह अप्रत्याशित संस्करण का उपयोग करने के लिए करता है, और तब से, आपकी बचत प्रत्येक परिवर्तन के लिए गुणा करती है।

यह रूबी के अलावा लोगों के समान ही है, रूबी के अलावा वे अपने कोड में और भी डेटा डालने लगते हैं (जो कोड से पूरी तरह से डेटा निकालने में बहुत मुश्किल बनाता है, जो हमेशा के लिए एक अच्छा लक्ष्य है अंतर्राष्ट्रीयकरण)।

हम्म, क्या मैंने उल्लेख किया है कि यदि आप इस तरह अपना डेटा निकालने में अच्छे हैं, तो i18n वस्तुतः मुफ़्त है?

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

+0

क्या आप वाकई अपने जीयूआई को इस तरह कोड करते हैं? : | –

+0

आपके जीयूआई को डेटा संचालित किए बिना पूरी तरह से कैसे लगाया जा सकता है? इतनी बार दोहराव है। –

+0

वैसे, String.split (स्ट्रिंगटोकनाइज़र होने के लिए उपयोग किया जाता है) इन वस्तुओं को पार्स करने में बहुत मदद कर सकता है। "फ़ाइल ... | * | fileMethod" जैसी स्ट्रिंग को इस मामले में एक दूसरे (* मतलब "शीर्ष स्तर" में पार्स किया जा सकता है - आप अपनी "भाषा" फ्लाई पर बना सकते हैं - रूबी डीएसएल की तरह लेकिन आसान) –

0
  1. अपने आवेदन के लिए आधार कार्रवाई बनाएं; यह आप अपने कोड में
  2. पर बाद में बेहद मदद कार्य बना है जाएगा आप के रूप में, बजाय अपने आधार कार्रवाई की उपवर्गों पक्ष

उन्हें व्यवस्थित करने के लिए, यह क्या आप उन लोगों के साथ कर रहे हैं पर निर्भर करेगा, और आप हो सकता है कि कुछ क्रियाएं एक तरह से व्यवस्थित हों और अन्य ने एक अलग तरीके बनाया हो। यह सब निर्भर करेगा।

क्या आप चाहते हैं कि आपके कोड में कोई कार्रवाई ढूंढने/बनाने का एक सतत तरीका हो।

आपके यूआई के आधार पर, आपको "स्थिर" क्रियाओं (यानी सामान जो आपके ऐप में हमेशा उपलब्ध है, जैसे मेनू सिस्टम) और गतिशील क्रियाओं के बीच अंतर करने की आवश्यकता हो सकती है जो केवल कुछ स्क्रीन या कुछ स्थानों पर बनाई जाती हैं।

किसी भी मामले में, आपके विशेष आधार क्रिया के ठोस उप-वर्गों का उपयोग करके आप इन चीजों को व्यवस्थित रखने में मदद करेंगे। आप नहीं चाहते हैं कि आपके कोड में सभी जगहों पर लेबल, निमोनिक्स और आइकन जैसी चीजें निर्दिष्ट करें।