2012-10-17 17 views
5

मुझे Shape नामक एक कक्षा मिली है जो जेपीनल से प्राप्त होती है।खींचे गए ऑब्जेक्ट पर क्लिक करना

बदले में कई उप-वर्ग Shape कक्षाओं का विस्तार करते हैं, प्रत्येक प्रकार के आकार के लिए एक।

प्रत्येक आकार का अपना ओवरड्रिएन paint() विधि है, जो संबंधित आकार खींचता है।

मैं किसी भी आकार पर क्लिक करने में सक्षम होना चाहता हूं, और अब इस तर्क को लागू करने की कोशिश कर रहा हूं। कृपया ध्यान दें कि प्रत्येक आकार को सरणी सूची में जोड़ा गया है।

हालांकि, इसमें कथन हमेशा झूठा लौटाता है, भले ही मैंने आकार के अंदर स्पष्ट रूप से क्लिक किया हो।

कोई विचार?

+0

ठीक है, आप पेंट आकार घटक की तरह कुछ योजना बना रहे हैं? – Takarakaka

+0

किस तरह के आकार? आपको 'शामिल' विधि को लागू करना होगा। यह अपने 'पेंट' विधि से खुद को उत्पन्न नहीं करेगा। –

+0

क्या आप कृपया कृपया @JanDvorak विस्तृत कर सकते हैं? अब तक कार्यक्रम काम करता है, जिससे स्क्रीन पर कई आकार खींचे जाते हैं। मेरी समस्या यह है कि मैं किसी भी आकार पर क्लिक नहीं कर सकता। –

उत्तर

10

कभी ओवरराइड JPanel में paint() बल्कि paintComponent(..)

इम काफी यकीन है कि नहीं मैं फिर भी समझ में मैं एक छोटी उदाहरण जो मुझे आशा है कि मदद मिलेगी बनाया है। मूल रूप से यह है DrawingPanel (मेरी अपनी कक्षा जो JPanel तक फैली हुई है और आकार खींचे जाते हैं)। यह पैनल आकार (केवल 2 के परीक्षण के लिए) का निर्माण करेगा उन्हें एक ArrayList को जोड़ने और उन्हें paintComponent(..) के माध्यम से JPanel और एक for पाश को आकर्षित, यह भी JPanel पर mouseClicked(..) evnets उपयोगकर्ता के लिए जाँच करने के लिए एक MouseAdapter है। जब कोई क्लिक करता है हम ArrayList में प्रत्येक Shape के माध्यम से पुनरावृति और जाँच करें कि क्या Shape बिंदु नहीं होता है या, और इसलिए अपने वर्ग के नाम प्रिंट और Shape किस प्रकार क्लिक किया और प्रिंट उचित संदेश है की जाँच करने के instance of का उपयोग करता है:

enter image description here

आउटपुट (दोनों आकार क्लिक करने के बाद):

क्लिक किया एक java.awt.geom.Rectangle2D $ डबल

एक आयताकार

पर क्लिक किया गया java.awt.geom पर क्लिक किया गया।Ellipse2D $ डबल

एक चक्र

क्लिक किया

ShapeClicker.java:

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Shape; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Rectangle2D; 
import java.util.ArrayList; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class ShapeClicker { 

    public ShapeClicker() { 
     JFrame frame = new JFrame(); 
     frame.setTitle("Shape Clicker"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 

     initComponents(frame); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     //create frame and components on EDT 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new ShapeClicker(); 
      } 
     }); 
    } 

    private void initComponents(JFrame frame) { 
     frame.add(new ShapePanel()); 
    } 
} 

//custom panel 
class ShapePanel extends JPanel { 

    private Shape rect = new Rectangle2D.Double(50, 100, 200, 100); 
    private Shape cirlce = new Ellipse2D.Double(260, 100, 100, 100); 
    private Dimension dim = new Dimension(450, 300); 
    private final ArrayList<Shape> shapes; 

    public ShapePanel() { 
     shapes = new ArrayList<>(); 
     shapes.add(rect); 
     shapes.add(cirlce); 
     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseClicked(MouseEvent me) { 
       super.mouseClicked(me); 
       for (Shape s : shapes) { 

        if (s.contains(me.getPoint())) {//check if mouse is clicked within shape 

         //we can either just print out the object class name 
         System.out.println("Clicked a "+s.getClass().getName()); 

         //or check the shape class we are dealing with using instance of with nested if 
         if (s instanceof Rectangle2D) { 
          System.out.println("Clicked a rectangle"); 
         } else if (s instanceof Ellipse2D) { 
          System.out.println("Clicked a circle"); 
         } 

        } 
       } 
      } 
     }); 
    } 

    @Override 
    protected void paintComponent(Graphics grphcs) { 
     super.paintComponent(grphcs); 
     Graphics2D g2d = (Graphics2D) grphcs; 
     for (Shape s : shapes) { 
      g2d.draw(s); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return dim; 
    } 
} 
+2

इसने समस्या को हल नहीं किया हालांकि मैं इस प्रयास की बहुत सराहना करता हूं। धन्यवाद :) –

3

यदि आप Shape लागू कर रहे हैं तो आपको contains विधि स्वयं को लागू करना होगा। Shape के लिए डिफ़ॉल्ट कार्यान्वयन हमेशा false देता है।

यदि आपका Shape घुमावों से घिरा हुआ है जो आपको पता है कि कैसे अंतर करना है (या निर्धारित करें कि कोई बिंदु एक या दूसरी तरफ है), तो आप even-odd rule का उपयोग कर सकते हैं। किसी भी दिशा में परीक्षण की गई बिंदु से एक रे को कास्ट करें जो सीधी रेखा के समानांतर नहीं है। यदि चौराहे की संख्या विषम है, तो बिंदु अंदर है। यदि चौराहे की संख्या भी है, तो बिंदु बाहर है।

निर्मित कक्षाएं इस पद्धति को लागू है, तो आप/उपयोग कर सकते हैं Polygon, Ellipse2D.Double या RoundRectangle2D.Double वर्ग का विस्तार करने और एक भरा बहुभुज/अंडाकार/दौर आयत है कि इसके अंदर जानता है।

+0

उत्तर के लिए धन्यवाद। चूंकि मेरे आकृति वर्ग ड्रॉ विधि को कॉल करते हैं और इस तरह के आकार को आकर्षित करते हैं, इसलिए वे वास्तव में आकृति वर्ग से बंधे नहीं हैं? –

+0

@ डॉटनेट आपने कहा था कि आपके पास 'आकार आरेखसूची' था? इसलिए, यदि आपने 'युक्त' विधि लागू की है तो जिस विधि को आपने कोशिश की है वह काम करेगा। –

+0

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