Java 当面板中的JButton悬停在JPanel上时,鼠标退出运行?

Java 当面板中的JButton悬停在JPanel上时,鼠标退出运行?,java,swing,jbutton,mouselistener,Java,Swing,Jbutton,Mouselistener,我有一个JPanel(我们称之为ctrlPanel),使用null布局,我在它的背景中放置了一个JLabel。在这个标签的顶部,我有另一个JLabel和一个JButton(默认情况下是隐藏的)。我想在用户将鼠标悬停在ctrlPanel上时显示标签和按钮 通过向ctrlPanel添加一个mouseAdapter,并在mouseEntered时调用showControls(),在mouseexite时调用hideControls(),可以(几乎)很好地工作。它们使用setVisible显示/隐藏顶部

我有一个JPanel(我们称之为ctrlPanel),使用null布局,我在它的背景中放置了一个JLabel。在这个标签的顶部,我有另一个JLabel和一个JButton(默认情况下是隐藏的)。我想在用户将鼠标悬停在ctrlPanel上时显示标签和按钮

通过向ctrlPanel添加一个mouseAdapter,并在mouseEntered时调用showControls(),在mouseexite时调用hideControls(),可以(几乎)很好地工作。它们使用setVisible显示/隐藏顶部的组件


但是,当用户将鼠标悬停在JButton上时,ctrlPanel似乎收到mouseExited调用,这使得JButton“闪烁”(mouseExited->mouseenterneted->mouseExited等等)。这对我来说没有意义,因为JButton在ctrlPanel中。我的意思是,将鼠标悬停在JLabel上没有问题。

我认为您想要的不是可行的-内部控制拦截鼠标事件。所以你可以

  • 创建一个鼠标侦听器,将其连接到面板、按钮等,并在任何地方正确处理这些内容
  • 检查mouseExited()处的坐标,如果鼠标仍在面板内,则忽略该事件

我也测试了这个,并惊讶地发现同样的结果。我猜Java组件处理鼠标入和鼠标出事件的方式与JavaScript和HTML不同(通过事件冒泡)。使用不同的布局管理器没有任何效果


我认为这是处理这个问题最安全的方法:创建一个定制的
JPanel
类,该类覆盖
add()
方法。这将委托给
super.add()
,但也将其自定义鼠标侦听器添加到传入的每个组件中。这样,您仍将获得鼠标输入和鼠标退出事件,但您将能够跟踪面板内的元素。无论您在鼠标退出时执行什么操作,面板都只会非常短暂地生效,并且会在下一个事件触发时立即撤消。您不应该看到对GUI的任何可见更改,但如果您看到闪烁,请尝试将窗口设置为双缓冲。

我如何处理此问题以及ixula的回答:

检查mouseExited()处的坐标,如果鼠标仍在面板内,则忽略该事件


您的JPanel可以是任何容器。

要更快获得更好的帮助,请发布一个。为了保持理智,请避免使用空布局。
public void mouseExited(MouseEvent e) {
    if(stillInPanel(e.getPoint())) return;
    // Exit logic
}

private boolean stillInPanel(Point2D p) {
    return (YOURJPANEL.contains((Point)p));
}