我需要幫助來了解Swing中的事件傳播。我知道每個事件只能由一個組件處理。因此,當我有一個面板outside
與一些兒童面板inside
,我添加mouseListeners他們兩個,將調用inside
之一。這很好,這是預期的行爲。子組件中的MouseMotionListener禁用父組件中的MouseListener
但我不明白,在下列情況下的行爲: inside
註冊了一個MouseMotionListener和outside
註冊一個MouseListener的。我期望inside
消耗所有MouseMotionEvents和outside
來接收MouseEvents,因爲inside
上沒有正常MouseEvents的偵聽器。但事實並非如此,inside
以某種方式消耗所有MouseEvent不僅僅是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的javadoc讓我覺得我的期望是正確的。所以,我需要一個不同的描述來理解它。
b)是否有更好的解決方案比以上草圖?
感謝, 席
編輯:現在還不清楚,爲什麼搖擺的行爲這種方式。但是看起來,獲得這些東西的唯一方法就是手動轉發事件,我會這樣做。
+1 [SSCCE(http://sscce.org/)。 – trashgod 2012-08-06 17:59:22