将事件传递给父母

我想创建一个应用程序,其中一些事件应该被处理,好像它们被传递到父容器一样。 例如,我有一个包含JLabel的JPanel。 顶级JPanel现在实现了鼠标拖动和拖动。 我需要做什么,以使事件看起来像他们到达JPanel而不是标签本身。 (更改源对象很重要)

有没有比实际实现事件并在父代中复制它们更好的解决方案? (在一些具有> 5个孩子的物体之后,这将变得乏味)。

在事件监听器中,您可以将事件分派给父组件。

作为myEvent的事件处理函数参数:

 Component source=(Component)myEvent.getSource(); source.getParent().dispatchEvent(myEvent); 

但是这个解决方案意味着为要添加的每个元素创建一个新的EventListener。

因此,您可以创建单个事件处理程序并重用它,将其添加到所有选定的子项中,如下所示:

 final Container parent=this; //we are a the parent container creation code MouseListener myCommonListener=new MouseListener() { @Override public void mouseClicked(MouseEvent e) { parent.dispatchEvent(e); } @Override public void mouseEntered(MouseEvent e) { parent.dispatchEvent(e); } @Override public void mouseExited(MouseEvent e) { parent.dispatchEvent(e); } @Override public void mousePressed(MouseEvent e) { parent.dispatchEvent(e); } @Override public void mouseReleased(MouseEvent e) { parent.dispatchEvent(e); } }; JLabel label=new JLabel("This is the first Label"); label.addMouseListener(myCommonListener); JLabel label2=new JLabel("This is the second Label"); label2.addMouseListener(myCommonListener); //... and so on 

您应该在将事件分派给父级之前转换事件。 转换包括到父亲亲属的坐标转换。

 public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{ public void mouseClicked(MouseEvent e) { redispatchToParent(e); } public void mousePressed(MouseEvent e) { redispatchToParent(e); } public void mouseReleased(MouseEvent e) { redispatchToParent(e); } public void mouseEntered(MouseEvent e) { redispatchToParent(e); } public void mouseExited(MouseEvent e) { redispatchToParent(e); } public void mouseWheelMoved(MouseWheelEvent e){ redispatchToParent(e); } public void mouseDragged(MouseEvent e){ redispatchToParent(e); } public void mouseMoved(MouseEvent e) { redispatchToParent(e); } private void redispatchToParent(MouseEvent e){ Component source = (Component) e.getSource(); MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent()); source.getParent().dispatchEvent(parentEvent); } } 

鼠标事件自动定位到具有鼠标侦听器的最深部件。

因此,为了实现您的目标,您可以简单地删除JLabel上的所有鼠标侦听器,它永远不会被选为鼠标事件的目标。

以下代码将以递归方式禁用给定组件及其子组件上的鼠标侦听器:

 private void disableMouseForComponent(Component... components) { for (Component c : components) { if (c instanceof Container) { disableMouseForComponent(((Container) c).getComponents()); } for (MouseListener l : c.getMouseListeners()) { c.removeMouseListener(l); } for (MouseMotionListener l : c.getMouseMotionListeners()) { c.removeMouseMotionListener(l); } } }