Java 在基础组件上触发鼠标事件

Java 在基础组件上触发鼠标事件,java,swing,events,Java,Swing,Events,我正在寻找一种将鼠标事件传递给其他组件所涵盖的组件的方法。为了说明我的意思,这里有一个示例代码。它包含两个jLabel,其中一个更小两倍,完全覆盖着一个更大的标签。但是,如果将鼠标悬停在标签上,则只有较大的标签才会触发mouseEntered事件 import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import

我正在寻找一种将鼠标事件传递给其他组件所涵盖的组件的方法。为了说明我的意思,这里有一个示例代码。它包含两个jLabel,其中一个更小两倍,完全覆盖着一个更大的标签。但是,如果将鼠标悬停在标签上,则只有较大的标签才会触发mouseEntered事件

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;

public class MouseEvtTest extends JFrame {

    public MouseEvtTest() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLayout(null);
        setSize(250, 250);

        MouseAdapter listener = new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.printf("Mouse entered %s label%n", e.getComponent().getName());
            }
        };
        LineBorder border = new LineBorder(Color.BLACK);

        JLabel smallLabel = new JLabel();
        smallLabel.setName("small");
        smallLabel.setSize(100, 100);
        smallLabel.setBorder(border);
        smallLabel.addMouseListener(listener);
        add(smallLabel);

        JLabel bigLabel = new JLabel();
        bigLabel.setName("big");
        bigLabel.setBorder(border);
        bigLabel.setSize(200, 200);
        bigLabel.addMouseListener(listener);
        add(bigLabel, 0); //Add to the front
    }

    public static void main(String[] args) {
        new MouseEvtTest().setVisible(true);
    }
}
当光标移动到较小标签上方的坐标时,在较小标签上触发鼠标输入事件的最佳方式是什么?如果有多个组件堆叠在一起,它将如何工作?其余的鼠标事件,如mouseClicked、mousePressed、MouseRelease等,如何处理?

在您的侦听器中:

bigLabel.dispatchEvent(mouseEvent);

当然,您必须将
biglab
定义为
final

要理解发生了什么,您需要理解Z-排序是如何工作的。作为快速概述,最后添加的组件将首先绘制。因此,在您的例子中,您希望在大组件之前添加小组件

// add(bigLabel, 0); //Add to the front
add(bigLabel); // add to the end so it is painted first

这可能有助于更好地解释这一点,并为您提供另一种选择。

请看一下Alexander Potochkin在

上的博客条目,很抱歉,但我只想问一下-您为什么要这样做?这似乎不是一件非常直观的事情,这通常意味着一个维护问题。这只是一个示例代码。真正的交易有一个不可见的面板,覆盖着一系列其他组件。顶部的面板根据不同的条件执行各种任务。例如,如果按住shift键,则可以抓住并移动整个零部件,使零部件位于下方。因为要解释真实生活场景的所有细节是很困难的(而且是不相关的),所以我认为这很好地说明了这个问题。此外,这可能不是最好的方法,但我无法重写组件(主要是因为时间)。谢谢,这帮助我解决了使用JLayeredPane验证覆盖时遇到的光标问题!这篇文章提出了一个非常好的解决方案。在示例代码中这样做可能看起来很愚蠢,但它非常接近我的真实场景。我故意将大标签添加到顶部,以便完全覆盖小标签。然后,您将负责自己编写命中检测代码,这意味着当在大标签上接收到鼠标事件时,您将需要遍历面板中的所有其他组件并使用contains(…)方法查看鼠标点是否在组件的边界内。如果是这样,那么您需要创建一个新的MouseEvent,并将其发送到上述组件。谢谢!这是最好的答案!