2012-08-06 17 views
9

में माउसलिस्टर को अक्षम करता है मुझे स्विंग में ईवेंट प्रचार को समझने में सहायता चाहिए। मुझे पता है कि प्रत्येक घटना को केवल एक घटक द्वारा संभाला जाता है। इस प्रकार, जब मेरे पास कुछ बच्चे पैनल inside के साथ पैनल outside है और मैं उनमें से दोनों को माउस लिस्टेनर्स जोड़ता हूं, तो inside में से एक को कॉल किया जाएगा। यह अच्छा है और यह अपेक्षित व्यवहार है।बाल घटक में माउसमोशन लिस्टनर मूल घटक

लेकिन मुझे निम्न स्थिति में व्यवहार को समझ में नहीं आता है: inside एक माउसमोशन लिस्टनर पंजीकृत करता है और outside एक माउस लिस्टर पंजीकृत करता है। मैं inside को MouseEvents प्राप्त करने के लिए सभी MouseMotionEvents और outside का उपभोग करने की अपेक्षा करता हूं, क्योंकि inside पर सामान्य MouseEvents के लिए कोई श्रोता नहीं है। लेकिन ऐसा नहीं है, inside किसी भी तरह से सभी MouseEvents को केवल माउसमोशन एवेन्ट्स का उपभोग नहीं करता है।

निम्नलिखित कोड समस्या दिखाता है:

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

public class EventTest { 
public static void main(String... args) { 
    SwingUtilities.invokeLater(new Runnable(){ 
     @Override 
     public void run() { 
      JComponent inside = new JPanel(); 
      inside.setBackground(Color.red); 
      inside.setPreferredSize(new Dimension(200,200)); 
      MouseMotionListener mm = new MouseMotionListener() { 
       @Override 
       public void mouseDragged(MouseEvent arg0) { 
        System.err.println("dragged");      
       } 
       @Override 
       public void mouseMoved(MouseEvent arg0) { 
        System.err.println("moved"); 
       } 
      }; 
      // next line disables handling of mouse clicked events in outside 
      inside.addMouseMotionListener(mm); 

      JComponent outside = new JPanel(); 
      outside.add(inside); 
      outside.setPreferredSize(new Dimension(300,300)); 
      outside.addMouseListener(new MouseAdapter() { 
       public void mouseClicked(MouseEvent e) { 
        System.err.println("clicked"); 
       } 
      }); 

      JFrame frame = new JFrame(); 
      frame.add(outside); 
      frame.pack(); 
      frame.setVisible(true); 
     } 
    }); 
    } 
} 

मैं समस्या को हल inside पर एक श्रोता दर्ज की सभी घटनाओं के लिए माता-पिता घटक में रुचि हो सकती है और फिर बुला dispatchEvent से काम कर सकता करने के लिए घटना को अग्रेषित करने के माता-पिता।

ए) क्या कोई मुझे कुछ दस्तावेज़ों में इंगित कर सकता है, जहां इस व्यवहार का वर्णन किया गया है? MouseEvent के जावडॉक्स ने मुझे यह सोचा कि मेरी अपेक्षाएं सही थीं। इसलिए, मुझे इसे समझने के लिए एक अलग विवरण की आवश्यकता है।

बी) क्या ऊपर एक स्केच से बेहतर समाधान है?

धन्यवाद, कैथरीन

संपादित करें: यह क्यों स्विंग इस तरह से व्यवहार करती है, यह स्पष्ट नहीं अब भी है। लेकिन जैसा दिखता है, सामानों को काम करने का एकमात्र तरीका घटनाओं को मैन्युअल रूप से अग्रेषित करना है, मैं इसे करूँगा।

+0

[sscce] के लिए +1 (http://sscce.org/)। – trashgod

उत्तर

8

ए) design द्वारा, जावा माउस ईवेंट केवल "बबल अप" होता है यदि बच्चे घटक पर कोई माउस श्रोता नहीं होता है।

बी) घटनाओं को दूसरे घटक में here और नीचे दिखाया जा सकता है।

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

public class EventTest { 

    public static void main(String... args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       final JComponent outside = new JPanel(); 
       JComponent inside = new JPanel(); 
       inside.setBackground(Color.red); 
       inside.setPreferredSize(new Dimension(200, 200)); 
       inside.addMouseMotionListener(new MouseAdapter() { 

        @Override 
        public void mouseDragged(MouseEvent e) { 
         System.err.println("dragged"); 
        } 

        @Override 
        public void mouseMoved(MouseEvent e) { 
         System.err.println("moved inside"); 
         outside.dispatchEvent(e); 
        } 
       }); 

       outside.add(inside); 
       outside.setPreferredSize(new Dimension(300, 300)); 
       outside.addMouseMotionListener(new MouseAdapter() { 

        @Override 
        public void mouseMoved(MouseEvent arg0) { 
         System.err.println("moved outside"); 
        } 
       }); 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(outside); 
       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
1

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

 MouseAdapter mm = new MouseAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent arg0) { 
       System.err.println("dragged");      
      } 
      @Override 
      public void mouseMoved(MouseEvent arg0) { 
       System.err.println("moved"); 
      } 
      @Override 
      public void mouseClicked(MouseEvent e) { 
       outside.dispatchEvent(e); 
      } 
     }; 
     // For forwarding events 
     inside.addMouseListener(mm); 
     // For consuming events you care about 
     inside.addMouseMotionListener(mm); 

मुझे भी dispatchEvent(e) विधि का उपयोग करने के आसपास कोई रास्ता नहीं मिला। मुझे लगता है कि आप उस मार्ग से फंस गए हैं।

0

यह मेरे लिए काम किया:

Ellipse2D mCircle = new Ellipse2D.Double(x,y,size,size); 

    void PassMouseEvent(MouseEvent e) { 
    getParent().dispatchEvent(e); 
    } 

    public void mousePressed(MouseEvent arg0) { 
    if(mCircle.contains(arg0.getX(), arg0.getY())) { 
     // Do stuff if we click on this object 
    } else { 
     // Pass to the underlying object to deal with the mouse event 
     PassMouseEvent(arg0); 
    } 
    } 
संबंधित मुद्दे