将一个jPanel上的click事件传递给另一个JPAnel

我有一个外面板,在外面板上我有另一个jPanel。

如果我右键单击内部面板,外部面板的右键单击操作应该会发生。 如果我左键单击内部面板,则应该发生其自己的内部面板的单击操作。

是否可以将点击事件从一个面板传递到另一个面板?

为解决此问题,您需要解决许多问题。

第一个是理解鼠标事件是创建它的组件的上下文,特别是位置信息。 点击点是源组件x / y位置的偏移量(鼠标事件将为0x0)。 这意味着如果要重新调度事件,则至少需要将位置上下文转换为父组件空间。

源组件也应该更改。 如果不这样做可能会导致API的其他部分出现问题,这些部分可能依赖于它来进行确定(例如弹出窗口,它会将位置信息从组件空间转换到屏幕空间)。

其次,你不应该对父母做出任何假设。 也就是说,您不应该假设父级可能实现或不实现鼠标侦听器接口。

一种可能的解决方案是使用SwingUtilities.convertMouseEvent将内部面板中引发的MouseEvent转换为与外部面板兼容,然后使用Component#dispatchEvent来模仿标准事件处理过程,例如……

 import java.awt.BorderLayout; 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; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; public class TestTree { public static void main(String[] args) { new TestTree(); } public TestTree() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new OutterPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class InnerPane extends JPanel { public InnerPane() { setBackground(Color.RED); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { System.out.println("Inner was clicked at : " + e.getPoint()); MouseEvent convertMouseEvent = SwingUtilities.convertMouseEvent(e.getComponent(), e, getParent()); getParent().dispatchEvent(convertMouseEvent); } }); } } public class OutterPane extends JPanel { public OutterPane() { setLayout(new BorderLayout()); setBorder(new EmptyBorder(10, 10, 10, 10)); add(new InnerPane()); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { System.out.println("Outter was clicked at : " + e.getPoint()); } }); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } } } 

你有没有在内板上尝试过类似的东西?

 void mouseClicked(MouseEvent e) { if ( e.getButton() == MouseEvent.BUTTON2 ) { outter.mouseClicked( e ); } else { // do job for your inner panel } } 

下面的代码对我有用

 JPanel parent = (JPanel) me.getComponent().getParent(); MouseMotionListener[] ml = parent.getMouseMotionListeners(); ml[0].mouseClicked(me); 

谢谢大家