2012-11-16 10 views
9

कुछ समय पहले मैंने जावा के साथ एक छोटा छवि दर्शक/प्रसंस्करण कार्यक्रम लिखा था, एक मिनी-फ़ोटोशॉप, यदि आप करेंगे।जावा आंतरिक कक्षा उपयोग और तत्काल

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

मैंने कुछ समय के लिए यह आश्चर्यचकित किया और आखिरकार इस समाधान का निर्माण किया, एक नई कक्षा जो एक छवि को जोड़ा जाने पर नए बटन के निर्माण को संभालती है। कोड निम्नानुसार है:

import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 


public class ImageList{ 

    private ArrayList<JMenuItem> list; 
    private ImageHandler main; 
    private ImageLevel img; 

    public ImageList() {} 

    public void setHandler(ImageHandler hand) { 
     main = hand; 
     img = main.getImg1(); 
    } 

    public void add(Buffer addi) { 
     final String added = addi.getName(); 
     JMenuItem uusi = new JMenuItem(added); 

     main.getMenu5().add(uusi); 
     uusi.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       img.setBuffer(added); 
       main.getScr().updateUI(); 
      } 
     }); 
    } 
} 

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

प्रोग्राम चल रहा है, जबकि विधि जोड़ने को कई बार कहा जाना चाहिए।

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

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

क्या कोई मुझे इस मुद्दे पर शिक्षित कर सकता है? क्या यह कोड यहां एक वर्ग है और नए बटन इसके उदाहरण हैं? क्या वे नए वर्ग हैं? क्या प्रत्येक नए बटन के लिए एक नई। क्लास-फ़ाइल होनी चाहिए? आदि ...

+3

पुन:। नामकरण: 'नया' एक आरक्षित शब्द है, इसलिए आपको उस जेएमएनयूइटेम चर के लिए कुछ अलग उपयोग करना चाहिए। – assylias

+0

@ पीटर इसे ठीक करेगा। – Valtteri

+0

ओपी के प्रश्न का उत्तर देने के लिए इस ['FileMenu'] (http://stackoverflow.com/a/4039359/230513) – trashgod

उत्तर

5

अक्सर, एक आंतरिक वर्ग एक कोड है जो केवल एक बार कहा जाता है में instantiated है (उदाहरण के लिए, जब आप JPanel का विस्तार करने और निर्माता में ActionListenersJButton को रों जोड़ें)। यहां, आप एक विधि में एक आंतरिक कक्षा को तुरंत चालू करते हैं जिसे आप कई बार कॉल करते हैं (यदि मैं आपका वर्णन सही ढंग से समझता हूं)। प्रत्येक बार जब आप add() पर कॉल करते हैं, तो आंतरिक कक्षा का एक नया उदाहरण बनाया जाएगा। नामित कक्षाओं के साथ, केवल एक वर्ग है, लेकिन कई उदाहरण हो सकते हैं।

+0

+1 में दिखाए गए अनुसार 'एक्शन' पर भी विचार करें। – Perception

+0

@ कोड-गुरु: ठीक है, तो वे नए उदाहरण हैं। वास्तव में कभी भी देखा नहीं, या कम से कम कभी नहीं देखा, एक से अधिक उदाहरण के साथ आंतरिक कक्षाएं। – Valtteri

+0

@ वाल्टटेरी बिल्कुल। एक नामित आंतरिक वर्ग के साथ एक ही चीज़ करने के बारे में स्पष्टीकरण के लिए [टेड होप का जवाब] देखें (http://stackoverflow.com/questions/13420151/java-inner-class-usage-and-instantiation/13420335#13420335)। जहां तक ​​यह उदाहरण बनाने से संबंधित है, दोनों बराबर हैं। –

0

आप अपने मेनू आइटम एक्शन श्रोताओं के लिए नए अज्ञात वर्ग बना रहे हैं।

मूल रूप से, अपने कोड

menuItem.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     img.setBuffer(added); 
     main.getScr().updateUI(); 
    } 
}); 

को परिभाषित करता है ActionListener

+2

यह सही नहीं है .... अज्ञात वर्ग संकलित समय पर रन टाइम नहीं बनाए जाते हैं। – Renato

+1

यह कोड एक * * * से नए * ऑब्जेक्ट * बनाता है। –

0
  • main.getScr().updateUI(); के लिए एक नया वर्ग कार्यान्वयन अद्यतन पहले से ही दिखाई दे घुमाओ वस्तुओं के लिए उचित तरीका नहीं है, इस विधि देखो और संवेदनशील महसूस है

  • JPanel का उपयोग करें (PreferredSize ओवरराइड करना न भूलें अन्यथा रिटर्न Dimension (0, 0)) paintComponent साथ,

  • आप OT तो हटाने का एक नया कंटेनर है कि तब छवि पकड़ आप के बजाय की छवियों के साथ revalidate() और repaint()


  • उपयोग JList कॉल करनी होगी जोड़ने चाहते हैं JMenuItem

  • ListSelectionListener टी जोड़ें ओ JList, तो आप betweens छवियों


  • यदि नहीं जोड़ा गया है किसी भी अन्य JComponent (रों) Container को Image रखती है, तो साथ JLabel उपयोग करने के लिए स्विच करने के लिए कर सकते हैं Icon/ImageIcon
+1

-1 ओपी के सवाल का जवाब नहीं देता है। –

+0

मूल सामग्री, यहां वर्णित अंधेरे में शॉट्स से बचने के लिए – mKorbel

+0

@mKorbel हाँ, मुझे पता है कि कोई इस तरह की सलाह के साथ मुझ पर आग लगाएगा: डी उनके लिए धन्यवाद। मैं अभी भी वास्तव में जीयूआई और इस तरह मूल रूप से समझ नहीं पा रहा हूं, इसलिए यह कोड बहुत थूक और इस्पात तार है और यह एक चमत्कार है जो इसे एक साथ रखता है ... किसी भी मामले में आपकी सलाह को समझ लेगा। – Valtteri

3

इस कोड में:

public void add(Buffer addi) { 
    . . . 
    uusi.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      img.setBuffer(added); 
      main.getScr().updateUI(); 
     } 
    }); 
} 

new ActionListener() {...} निर्माण एक अज्ञात आंतरिक वर्ग है। यह व्यवहार करता है जैसे कि इसे नियमित आंतरिक कक्षा के रूप में अलग से घोषित किया गया था। मुख्य अंतर यह है कि नाम संकलक द्वारा स्वचालित रूप से उत्पन्न होता है।

private class Anonymous implements ActionListener { 
    public void actionPerformed(ActionEvent e) { 
     img.setBuffer(added); 
     main.getScr().updateUI(); 
    } 
} 

public void add(Buffer addi) { 
    . . . 
    uusi.addActionListener(new Anonymous()); 
} 

हर बार जब आप अपने addActionListener कोड निष्पादित, यह इस वर्ग का एक नया उदाहरण बनाता है: यह के बराबर है।

बेनामी आंतरिक कक्षाओं में कुछ अन्य प्रतिबंध हैं जो अज्ञात होने के परिणाम हैं। उदाहरण के लिए, यदि वे फ़ील्ड घोषित करते हैं, तो फ़ील्ड कक्षा के भीतर से केवल पहुंच योग्य (प्रतिबिंब का उपयोग किए बिना) हैं।

+0

+1 समकक्ष समझाते हुए +1 एक नामित आंतरिक वर्ग –

+0

दोनों के बीच का अंतर यह है कि अनाम आंतरिक कक्षा में इसके संदर्भ (''जोड़ा') के 'अंतिम' स्थानीय चर तक पहुंच है, लेकिन 'अनामित' वर्ग जैसा आपने लिखा है, यह नहीं है (क्योंकि यह विधि के बाहर है)। आप 'एडी' विधि के अंदर 'निजी वर्ग बेनामी' को ओपी के कोड के बराबर बराबर बनाने के लिए स्थानांतरित कर सकते हैं। –

+0

main.getScr()। UpdateUI(); कृपया इस कोड लाइन में क्या मान्य है ??? – mKorbel

0

आप जो कर रहे हैं वह इंटरफ़ेस एक्शनलिस्टर का अज्ञात कार्यान्वयन बना रहा है। प्रत्येक अज्ञात कार्यान्वयन में अपनी स्वयं की क्लास फ़ाइल होगी (जिसे ImageList $ 1.class, ImageList $ 2.class और इसी तरह कहा जाता है)।

तुम भी इसी तरह के परिणाम के साथ कुछ इस तरह कर सकता है,:

class MyActionListener implements ActionListener { 
    public void actionPerformed(ActionEvent e) { 
     img.setBuffer(added); 
     main.getScr().updateUI(); 
    } 
}; 

menuItem.addActionListener(new MyActionListener()); 
0

एक क्लास के भीतर एक आंतरिक वर्ग है फ़ाइल .class 'माता-पिता' में संकलित करता है। आपके पास 1 कक्षा के अंदर कई आंतरिक कक्षाएं हो सकती हैं। (जिसके परिणामस्वरूप 1।संकलन के बाद कक्षा फाइलें) एक आंतरिक क्लास (रनटाइम) में प्रत्येक 'कॉल' उस आंतरिक क्लास ('मानक श्रेणी' के समान) का एक वस्तु बना देगा। लेकिन यह आपकी .class फ़ाइलों को बदल दिया है।

तो जब एक ही प्रकार के 3 बटन जोड़ें, तो हर बार tha आंतरिक क्लास का एक नया ऑब्जेक्ट बनाया जाएगा। बटन के लिए एक ही सिद्धांत के रूप में।

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