java - एक जेपीनेल में एक छवि कैसे जोड़ें?




image swing (10)

मेरे पास एक JPanel है जिसमें मैं जेपीईजी और पीएनजी छवियों को जोड़ना चाहता हूं जो मैं फ्लाई पर उत्पन्न करता हूं।

स्विंग ट्यूटोरियल में अब तक के सभी उदाहरण मैंने देखा है, विशेष रूप से स्विंग उदाहरणों में ImageIcon उपयोग करें।

मैं इन छवियों को बाइट एरे के रूप में उत्पन्न कर रहा हूं, और वे आम तौर पर 640x480 पर उदाहरणों में उपयोग किए जाने वाले आम आइकन से बड़े होते हैं।

  1. क्या JPIel में आकार वाली छवि प्रदर्शित करने के लिए ImageIcon क्लास का उपयोग करने में कोई (प्रदर्शन या अन्य) समस्या है?
  2. ऐसा करने का सामान्य तरीका क्या है?
  3. ImageIcon क्लास का उपयोग किये बिना जेपीनल में कोई छवि कैसे जोड़ें?

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


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

अपनी प्रोजेक्ट निर्देशिका में एक स्रोत फ़ोल्डर बनाएं, इस मामले में मैंने इसे छवियां कहा है।

JFrame snakeFrame = new JFrame();
snakeFrame.setBounds(100, 200, 800, 800);
snakeFrame.setVisible(true);
snakeFrame.add(new JLabel(new ImageIcon("Images/Snake.png")));
snakeFrame.pack();

आप जेपीनेल को उप-वर्गीकृत कर सकते हैं - यहां मेरी छविपैनेल से निकाला गया है, जो 5 स्थानों में से किसी एक में, शीर्ष / बाएं, ऊपर / दाएं, मध्य / मध्य, नीचे / बाएं या नीचे / दाएं:

protected void paintComponent(Graphics gc) {
    super.paintComponent(gc);

    Dimension                           cs=getSize();                           // component size

    gc=gc.create();
    gc.clipRect(insets.left,insets.top,(cs.width-insets.left-insets.right),(cs.height-insets.top-insets.bottom));
    if(mmImage!=null) { gc.drawImage(mmImage,(((cs.width-mmSize.width)/2)       +mmHrzShift),(((cs.height-mmSize.height)/2)        +mmVrtShift),null); }
    if(tlImage!=null) { gc.drawImage(tlImage,(insets.left                       +tlHrzShift),(insets.top                           +tlVrtShift),null); }
    if(trImage!=null) { gc.drawImage(trImage,(cs.width-insets.right-trSize.width+trHrzShift),(insets.top                           +trVrtShift),null); }
    if(blImage!=null) { gc.drawImage(blImage,(insets.left                       +blHrzShift),(cs.height-insets.bottom-blSize.height+blVrtShift),null); }
    if(brImage!=null) { gc.drawImage(brImage,(cs.width-insets.right-brSize.width+brHrzShift),(cs.height-insets.bottom-brSize.height+brVrtShift),null); }
    }

आप मुफ्त SwingX पुस्तकालयों से JXImagePanel क्लास का उपयोग कर अपने स्वयं के घटक सबक्लास को पूरी तरह से रोल करने से बच सकते हैं।

Download


मुझे लगता है कि किसी चीज के उप-वर्ग की आवश्यकता नहीं है। बस एक जेलाबेल का प्रयोग करें। आप एक छवि को एक जेलाबेल में सेट कर सकते हैं। तो, Jlabel का आकार बदलें और फिर इसे एक छवि के साथ भरें। यह ठीक है। यह वही तरीका है जो मैं करता हूं।


मैं एक निजी परियोजना में बहुत कुछ कर रहा हूं जिस पर मैं काम कर रहा हूं। इस प्रकार मैंने 1024x1024 तक छवियों को बिना किसी समस्या के (स्मृति को छोड़कर) उत्पन्न किया है और उन्हें बहुत जल्दी और बिना किसी प्रदर्शन समस्याओं के प्रदर्शित कर सकते हैं।

जेपीनल सबक्लास की पेंट विधि को ओवरराइड करना अधिक है और आपको करने की आवश्यकता से अधिक काम की आवश्यकता है।

जिस तरह से मैं करता हूं वह है:

Class MapIcon implements Icon {...}

या

Class MapIcon extends ImageIcon {...}

छवि उत्पन्न करने के लिए आप जिस कोड का उपयोग करते हैं वह इस वर्ग में होगा। जब मैं paintIcon () कहा जाता है, तो gufrawImvge (bufferedImage) का उपयोग करते समय मैं एक बुफर्ड इमेज का उपयोग करने के लिए उपयोग करता हूं; इससे आपकी छवियां उत्पन्न करते समय फ्लैशिंग की मात्रा कम हो जाती है, और आप इसे थ्रेड कर सकते हैं।

अगला मैं जेएलएबल का विस्तार करता हूं:

Class MapLabel extends Scrollable, MouseMotionListener {...}

ऐसा इसलिए है क्योंकि मैं अपनी छवि को स्क्रॉल फलक पर रखना चाहता हूं, मैं छवि का हिस्सा प्रदर्शित करता हूं और उपयोगकर्ता को आवश्यकतानुसार चारों ओर स्क्रॉल करना पड़ता है।

तो मैं MapLabel को पकड़ने के लिए एक JScrollPane का उपयोग करता हूं, जिसमें केवल MapIcon होता है।

MapIcon map = new MapIcon (); 
MapLabel mapLabel = new MapLabel (map);
JScrollPane scrollPane = new JScrollPane();

scrollPane.getViewport ().add (mapLabel);

लेकिन आपके परिदृश्य के लिए (हर बार पूरी छवि दिखाएं)। आपको MapLabel को शीर्ष जेपीनेल में जोड़ने की ज़रूरत है, और सुनिश्चित करें कि उन्हें छवि के पूर्ण आकार (GetPreferredSize () को ओवरराइड करके) आकार दें।


यदि आप जेपीनल का उपयोग कर रहे हैं, तो शायद स्विंग के साथ काम कर रहे हैं। इसे इस्तेमाल करे:

BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
add(picLabel);

छवि अब एक स्विंग घटक है। यह किसी अन्य घटक की तरह लेआउट स्थितियों के अधीन हो जाता है।


यह उत्तर @ शावल्ली के उत्तर का पूरक है ...

मैं अपने जार के भीतर भी एक छवि का संदर्भ देना चाहता था, लेकिन BufferedImage रखने के बजाय, मैंने यह सरल किया:

 JPanel jPanel = new JPanel();      
 jPanel.add(new JLabel(new ImageIcon(getClass().getClassLoader().getResource("resource/images/polygon.jpg"))));

JPanel लगभग हमेशा गलत वर्ग के लिए गलत वर्ग है। आप JComponent उप JComponent क्यों नहीं होगा?

ImageIcon साथ एक मामूली समस्या है जिसमें कन्स्ट्रक्टर छवि को पढ़ने के ब्लॉक करता है। एप्लिकेशन जार से लोड होने पर वास्तव में कोई समस्या नहीं है, लेकिन हो सकता है कि आप संभावित रूप से नेटवर्क कनेक्शन पर पढ़ रहे हों। ImageObserver डेमो में भी MediaTracker , ImageObserver और दोस्तों का उपयोग करने के बहुत सारे एडब्ल्यूटी-युग उदाहरण हैं।


JLabel imgLabel = new JLabel(new ImageIcon("path_to_image.png"));




jpanel