【发布时间】:2012-08-06 15:14:29
【问题描述】:
我需要帮助来理解 Swing 中的事件传播。我知道每个事件仅由一个组件处理。因此,当我有一个面板 outside 和一些子面板 inside 并且我将 mouseListeners 添加到它们两者时,将调用 inside 之一。这很好,这是预期的行为。
但我不明白以下情况下的行为:
inside 注册一个 MouseMotionListener,outside 注册一个 MouseListener。我希望 inside 消耗所有 MouseMotionEvents 和 outside 来接收 MouseEvents,因为在 inside 上没有正常 MouseEvents 的侦听器。但事实并非如此,inside 不知何故消耗了所有 MouseEvents,而不仅仅是 MouseMotionEvents。
以下代码说明了问题:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EventTest {
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
JComponent inside = new JPanel();
inside.setBackground(Color.red);
inside.setPreferredSize(new Dimension(200,200));
MouseMotionListener mm = new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent arg0) {
System.err.println("dragged");
}
@Override
public void mouseMoved(MouseEvent arg0) {
System.err.println("moved");
}
};
// next line disables handling of mouse clicked events in outside
inside.addMouseMotionListener(mm);
JComponent outside = new JPanel();
outside.add(inside);
outside.setPreferredSize(new Dimension(300,300));
outside.addMouseListener( new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
System.err.println("clicked");
}
});
JFrame frame = new JFrame();
frame.add(outside);
frame.pack();
frame.setVisible(true);
}
});
}
}
我可以通过在inside 上为父组件可能感兴趣的所有事件注册一个侦听器来解决此问题,然后调用 dispatchEvent 将事件转发给父组件。
a) 有人可以指点我一些文档,其中描述了这种行为吗? MouseEvent 的 javadocs 让我觉得我的期望是正确的。所以,我需要一个不同的描述来理解它。
b) 有没有比上述方案更好的解决方案?
谢谢, 凯瑟琳
编辑:目前还不清楚为什么 Swing 会这样。但看起来,让这些东西正常工作的唯一方法是手动转发事件,我会这样做。
【问题讨论】:
-
为sscce+1。
标签: java swing events mouse-listeners