在JPanel上的任何位置检测鼠标进入/退出事件

Man*_*ano 14 java

基本上,当鼠标进入JPanel区域并退出JPanel区域时,我想知道一个JPanel.所以我添加了一个鼠标监听器,但是如果JPanel上有组件并且鼠标经过其中一个组件,则它被检测为JPanel上的一个出口,即使该组件位于JPanel上.我想知道是否有人知道如何解决这个问题,而不需要像在JPanel上的所有组件上添加监听器那样?

Dar*_*oux 9

有一个非常简单的解决方案可以解决这个问题:

public class MyJPanel implements MouseListener {

    public void mouseExited(MouseEvent e) {
        java.awt.Point p = new java.awt.Point(e.getLocationOnScreen());
        SwingUtilities.convertPointFromScreen(p, e.getComponent());
        if(e.getComponent().contains(p)) {return;}
        ...//the rest of your code
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

这样,只要在子元素上发生mouseExited事件,就会忽略它.


Ash*_*Ash 8

以下是为可能包含其他组件的组件执行此操作的一种方法:

  1. 添加全局AWT事件侦听器以获取所有鼠标事件.例如:

    Toolkit.getDefaultToolkit().addAWTEventListener( 
       new TargetedMouseHandler( panel ), AWTEvent.MOUSE_EVENT_MASK );
    
    Run Code Online (Sandbox Code Playgroud)
  2. 实现TargetedMouseHandler忽略不是由面板或面板的一个子项(您可以SwingUtilities.isDescendingFrom用来测试)的事件.

  3. 跟踪鼠标是否已经在面板的范围内.当您MouseEvent.MOUSE_ENTERED在面板或其中一个子项中获得事件时,请将标志设置为true.

  4. 当您获得某个MouseEvent.MOUSE_EXITED事件时,只有当该点位于MouseEvent目标面板范围之外时才重置该标志.SwingUtilities.convertPointComponent.getBounds().contains()会在这里派上用场.


Ita*_*man 0

如果您希望将所有事件发送到顶级窗口,您可以向 JFrame 的玻璃窗格添加一个侦听器。请参阅getGlassPane