Java事件传播停止

问题描述:

我有一个主窗口: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

我不认为你可以。我相信这是一个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

在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://*.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://*.com/q/2159803/230513)。 – trashgod 2012-08-06 18:05:43

+0

如果您无法访问父级,您如何宣传活动? – 2015-07-19 18:36:45

+0

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