我有一个外面板,在外面板上我放置了另一个jPanel。
如果我右键单击内部面板,则应执行外部面板的右键单击操作。如果我左键单击内部面板,则应该发生其自己的内部面板的单击操作。
是否可以将点击事件从一个面板传递到另一个面板?
答案 0 :(得分:4)
为解决此问题,您需要解决一些问题。
首先要了解鼠标事件是创建它的组件的上下文,特别是位置信息。点击点是源组件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);
}
}
}
答案 1 :(得分:0)
您是否尝试过内部面板中的内容?
void mouseClicked(MouseEvent e) {
if ( e.getButton() == MouseEvent.BUTTON2 ) {
outter.mouseClicked( e );
}
else {
// do job for your inner panel
}
}
答案 2 :(得分:0)
以下代码为我工作
JPanel parent = (JPanel) me.getComponent().getParent();
MouseMotionListener[] ml = parent.getMouseMotionListeners();
ml[0].mouseClicked(me);
全部谢谢