Java 将一个jPanel上的click事件传递给另一个jPanel
我有一个外部面板,在外部面板上放置了另一个jPanel 如果我在内部面板上单击鼠标右键,外部面板的右键单击操作应该会发生。如果我在内部面板上单击鼠标左键,它自己的内部面板的单击操作就会发生Java 将一个jPanel上的click事件传递给另一个jPanel,java,swing,jpanel,mouseevent,Java,Swing,Jpanel,Mouseevent,我有一个外部面板,在外部面板上放置了另一个jPanel 如果我在内部面板上单击鼠标右键,外部面板的右键单击操作应该会发生。如果我在内部面板上单击鼠标左键,它自己的内部面板的单击操作就会发生 是否可以将单击事件从一个面板传递到另一个面板?您是否在内部面板中尝试过类似的操作 void mouseClicked(MouseEvent e) { if ( e.getButton() == MouseEvent.BUTTON2 ) { outter.mouseClicked
是否可以将单击事件从一个面板传递到另一个面板?您是否在内部面板中尝试过类似的操作
void mouseClicked(MouseEvent e) {
if ( e.getButton() == MouseEvent.BUTTON2 ) {
outter.mouseClicked( e );
}
else {
// do job for your inner panel
}
}
你在你的内板上试过类似的东西吗
void mouseClicked(MouseEvent e) {
if ( e.getButton() == MouseEvent.BUTTON2 ) {
outter.mouseClicked( e );
}
else {
// do job for your inner panel
}
}
您需要解决一些问题才能使其正常工作 第一个是理解鼠标事件与创建它的组件相关,特别是位置信息。单击点是源组件x/y位置的偏移量(鼠标事件的偏移量为0x0)。这意味着,如果要重新修补事件,至少需要将位置上下文转换为父组件空间 源组件也应该更改。如果不这样做,可能会导致API的其他部分出现问题,这些部分可能依赖于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);
}
}
}
您需要解决一些问题才能使其正常工作 第一个是理解鼠标事件与创建它的组件相关,特别是位置信息。单击点是源组件x/y位置的偏移量(鼠标事件的偏移量为0x0)。这意味着,如果要重新修补事件,至少需要将位置上下文转换为父组件空间 源组件也应该更改。如果不这样做,可能会导致API的其他部分出现问题,这些部分可能依赖于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);
}
}
}
下面的代码对我有用
JPanel parent = (JPanel) me.getComponent().getParent();
MouseMotionListener[] ml = parent.getMouseMotionListeners();
ml[0].mouseClicked(me);
谢谢下面的代码为我工作
JPanel parent = (JPanel) me.getComponent().getParent();
MouseMotionListener[] ml = parent.getMouseMotionListeners();
ml[0].mouseClicked(me);
谢谢大家设计是否扩展了JPanel?若然,原因为何?另外,
MouseListener
是一个非常低级的监听器,可以添加到JPanel
。右键单击会发生什么?是的,它扩展了jPanel。两个不同的动态菜单。这些菜单将在运行时决定。设计是否扩展JPanel?若然,原因为何?另外,MouseListener
是一个非常低级的监听器,可以添加到JPanel
。右键单击会发生什么?是的,它扩展了jPanel。两个不同的动态菜单。这些菜单将在运行时决定。问题在于MouseEvent
所需的信息与内部面板相关,即源代码和位置等信息与内部面板相关。如果OP想要独立地使用这些值(即,outter面板不需要决定鼠标事件的状态),这可能会严重地把事情搞砸。MouseEvent
所需的信息与内部面板相关,也就是说,source
和position
是相对于内面板的。如果OP想要独立地使用这些值,这可能会把事情搞砸(也就是说,outter面板不需要对鼠标事件的状态做出决定)这不会将MouseEvent
转换为父组件上下文,并且MouseMotionListener
没有mouseClicked
事件…是。你的答案是一个更好的解决方案感谢这不会将MouseEvent
转换为父组件上下文,并且MouseMotionListener
没有mouseClicked
事件…是。你的答案是一个更好的解决方案谢谢