2010-08-30 184 views
8

我有一個主窗口:Java事件傳播停止

public class MainPanel extends JFrame implements MouseListener { 

    public MainPanel() { 
     setLayout(new FlowLayout()); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     addMouseListener(this); 

     ChildPanel child = new ChildPanel(); 
     add(child); 

     JPanel spacer = new JPanel(); 
     spacer.setPreferredSize(new Dimension(50, 50)); 
     add(spacer); 

     pack(); 
     setLocationRelativeTo(null); 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on MainPanel"); 
    } 
} 

和一個孩子的JPanel:

public class ChildPanel extends JPanel implements MouseListener { 

    public ChildPanel() { 
     setBackground(Color.RED); 
     setPreferredSize(new Dimension(200, 200)); 
     //addMouseListener(this); 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on ChildPanel"); 
    } 
} 

與子板註釋掉調用addMouseListener,父收到單擊事件時我點擊窗口中的任何地方,包括孩子。如果我取消註釋該電話並點擊子面板,只有孩子接收到點擊事件,並且不傳播給父母。

如何阻止該事件被兒童消耗?

+1

那怪異的......我記得有當父母被消耗在孩子束縛的鼠標事件 – TheLQ 2010-08-31 01:01:09

回答

3

我不認爲你可以。我相信這是一個Swing設計原則,只有一個組件接收事件。

但是,您可以獲得所需的行爲,但將JFrame傳遞給ChildPanel並調用其mouseClicked(MouseEvent)或任何您想要的方法。或者只是獲取父組件。

@Override 
    public void mouseClicked(MouseEvent e) { 
     System.out.println("Mouse click event on ChildPanel"); 
     this.frame.mouseClicked(e); 
     getParent().mouseClicked(e); 
    } 
+3

我警惕通過這種方法隱含的緊耦合的相反的問題。 – trashgod 2010-08-31 04:15:01

+2

看起來我會用getParent()去,除非我能想到一種方法來改變我的項目,所以父母和孩子都不需要處理事件。將事件處理限制在一個組件看起來像是一個荒謬的設計決定... – takteek 2010-08-31 19:09:08

5

在Swing中,您通常希望點擊組件響應;但您可以將轉發給父代的鼠標事件,如下所示。這裏有一個相關的example

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** @see https://stackoverflow.com/questions/3605086 */ 
public class ParentPanel extends JPanel { 

    public ParentPanel() { 
     this.setPreferredSize(new Dimension(640, 480)); 
     this.setBackground(Color.cyan); 
     this.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Mouse clicked in parent panel."); 
      } 
     }); 
     JPanel child = new JPanel(); 
     child.setPreferredSize(new Dimension(320, 240)); 
     child.setBackground(Color.blue); 
     child.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       System.out.println("Mouse clicked in child panel."); 
       ParentPanel.this.processMouseEvent(e); 
      } 
     }); 
     this.add(child); 
    } 

    private void display() { 
     JFrame f = new JFrame("MouseEventTest"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ParentPanel().display(); 
      } 
     }); 
    } 
} 
+0

參見[*'EventListenerList'激發順序*](http://stackoverflow.com/q/2159803/230513)。 – trashgod 2012-08-06 18:05:43

+0

如果您無法訪問父級,您如何宣傳活動? – 2015-07-19 18:36:45

+0

我想在'SwingUtilities'和提到的擴展[這裏](http://stackoverflow.com/a/17631267/230513)。 – trashgod 2015-07-19 20:32:40