gpt4 book ai didi

java - 子组件中的 MouseMotionListener 禁用父组件中的 MouseListener

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:18:51 24 4
gpt4 key购买 nike

我需要帮助来理解 Swing 中的事件传播。我知道每个事件只由一个组件处理。因此,当我有一个面板 outside 和一些子面板 inside 并且我将 mouseListeners 添加到它们两个时, inside 将被调用.这很好,这是预期的行为。

但我不明白以下情况下的行为:inside 注册一个 MouseMotionListener,outside 注册一个 MouseListener。我希望 inside 消耗所有 MouseMotionEvents 和 outside 接收 MouseEvents,因为 inside 上没有普通 MouseEvents 的监听器。但事实并非如此,inside 以某种方式消耗了所有 MouseEvent,而不仅仅是 MouseMotionEvent。

下面的代码说明了这个问题:

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) 是否有比上面概述的解决方案更好的解决方案?

谢谢,凯瑟琳

编辑:目前还不清楚为什么 Swing 会这样。但看起来,让这些东西正常工作的唯一方法是手动转发事件,我会这样做。

最佳答案

a) 通过 design ,只有在子组件上没有鼠标监听器时,Java 鼠标事件才会“冒泡”。

b) 您可以转发事件到另一个组件,如图所示here及以下。

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() {
final JComponent outside = new JPanel();
JComponent inside = new JPanel();
inside.setBackground(Color.red);
inside.setPreferredSize(new Dimension(200, 200));
inside.addMouseMotionListener(new MouseAdapter() {

@Override
public void mouseDragged(MouseEvent e) {
System.err.println("dragged");
}

@Override
public void mouseMoved(MouseEvent e) {
System.err.println("moved inside");
outside.dispatchEvent(e);
}
});

outside.add(inside);
outside.setPreferredSize(new Dimension(300, 300));
outside.addMouseMotionListener(new MouseAdapter() {

@Override
public void mouseMoved(MouseEvent arg0) {
System.err.println("moved outside");
}
});

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(outside);
frame.pack();
frame.setVisible(true);
}
});
}
}

关于java - 子组件中的 MouseMotionListener 禁用父组件中的 MouseListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11831029/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com