There are a number issues you need to resolve for this to work.
The first is understanding that a mouse event is contextual to the component that created it, in particular, the location information. The click point is the offset from the source components x/y position (which will be 0x0 for the mouse event). This means if you want to redispatch the event, you need to, at least, translate the location context into the parent components space.
The source component should also be changed. Failing to do this could cause issues for other parts of the API that may rely on it to make determinations (such as a popup, which will want to translate the location information from the component space to the screen space).
Secondly, you should make no assumptions about the parent. That is, you should make no assumption that the parent may or may not implement a mouse listener interfaces.
A possible solution would be to use SwingUtilities.convertMouseEvent
to convert the MouseEvent
raised in the inner panel to be compatible with the outer panel and then use Component#dispatchEvent
to mimick the standard event handling process, for example...
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);
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…