当面板中的 JButton 悬停时,JPanel 上的 MouseExited 运行?

Posted

技术标签:

【中文标题】当面板中的 JButton 悬停时,JPanel 上的 MouseExited 运行?【英文标题】:MouseExited on JPanel runs when JButton in panel hovered over? 【发布时间】:2011-07-23 02:27:59 【问题描述】:

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

通过将 mouseAdapter 添加到 ctrlPanel 并在 mouseEntered 时调用 showControls() 并在 mouseExited 时调用 hideControls() ,它(几乎)可以正常工作。这些使用 setVisible 显示/隐藏顶部的组件。

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

【问题讨论】:

如需尽快获得更好的帮助,请发帖 SSCCE。为了理智起见,请避免使用空布局。 【参考方案1】:

我做了什么来解决这个问题,就像 ixula 的回答一样:

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

public void mouseExited(MouseEvent e) 
    if(stillInPanel(e.getPoint())) return;
    // Exit logic


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

其中 YOURJPANEL 可以是任何容器。

【讨论】:

【参考方案2】:

我也对此进行了测试,并惊讶地发现了相同的结果。我猜 Java 的组件不像 javascripthtml 那样处理鼠标移入和移出事件(通过事件冒泡)。使用不同的布局管理器没有任何效果。

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于当面板中的 JButton 悬停时,JPanel 上的 MouseExited 运行?的主要内容,如果未能解决你的问题,请参考以下文章

通过按JButton在随机JPanel上绘制圆圈

JButton 位于不应该在其上的 JPanel [关闭]

为什么我的JButton在放入JPanel的构造函数时不显示?

鼠标在内部组件悬停时退出

在 JPanel.getComponents() 中循环时如何获取 JButton 属性

Java Swing 在单击我要删除的 jpanel 中存在的 Jbutton 时删除 Jpanel