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的调用,当我单击窗口中的任何位置(包括子项)时,父级会收到单击事件。 如果我取消注释该调用并单击子面板,则只有子节点接收到click事件,并且它不会传播到父节点。

如何阻止儿童食用该事件?

我认为你不能。 我相信这是一个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); } 

在Swing中,您通常希望单击的组件响应; 但您可以将鼠标事件转发给父级,如下所示。 这是一个相关的例子 。

 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(); } }); } }