我实现了一个简单的鼠标监听器,只要鼠标进入组件(JPanel),背景颜色就会改变,只要鼠标离开,它就会恢复。这有一些问题:
我猜这对于Swing老兵来说很容易。对于如何解决这个问题,有任何的建议吗?我不想使用计时器等...
答案 0 :(得分:6)
如果我将鼠标移动到孩子身上 很快,mouseEnter事件不是 烧制
我从未见过这种情况发生过,但如果这是一个问题,那么你可以处理mouseMoved而不是重置背景。
如果我的组件有孩子,那么 鼠标移动到它触发的孩子 mouseExit
使用以下测试,只有在离开组件边界时才会执行代码:
public void mouseExited(MouseEvent e)
{
if (! getVisibleRect().contains(e.getPoint()) )
{
setBackground(...);
}
}
答案 1 :(得分:3)
有许多解决方案:
AWTEventListener
添加到默认Toolkit
并过滤您感兴趣的事件。遗憾的是,这需要获得安全权限。EventQueue
并过滤活动。这需要安全权限,让applet和WebStart / JNLP应用程序获得该权限。答案 2 :(得分:1)
在容器上尝试各种方法后,没有成功,我最终使用 Timer 。我的容器包含已经需要鼠标监听器的元素并没有帮助。
计时器方法也意味着我可以在短时间内延迟更改。 (在我的例子中,我在树节点(容器)中显示其他按钮,以及更改背景。)
在容器上的 mouseEntered()上,创建 Timer (如果不存在),每260毫秒重复一次。在每次调用Timer时,它确定鼠标是否在容器内。如果是这样,它第一次发出鼠标悬停信号。如果没有,它会发出非鼠标悬停信号并停止计时器。
在Scala中,如下所示,方法调用 entryExit()编码鼠标是否结束(具有相同值的多个调用没有影响):
abstract class MouseInterpreter(component: JComponent) extends MouseAdapter {
...
private var mouseOverAction: () => Unit = () => {}
private var mouseOverTimer: Option[Timer] = None
...
def entryExit(entered: Boolean) // this is an abstract method
override def mouseEntered(e: MouseEvent) {
if (mouseOverTimer.isEmpty) {
val aTimer = new Timer(260, new ActionListener {
def actionPerformed(e: ActionEvent) {
mouseOverAction()
}
})
mouseOverTimer = Some(aTimer)
mouseOverAction = () => {
mouseOverAction = () => {
val point = MouseInfo.getPointerInfo.getLocation
SwingUtilities.convertPointFromScreen(point, component)
if (component.getVisibleRect.contains(point))
entryExit(entered = true)
else {
entryExit(entered = false)
aTimer.stop()
mouseOverTimer = None
mouseOverAction = () => {}
}
}
}
aTimer.setRepeats(true)
aTimer.start()
}
}
...
}
答案 3 :(得分:0)
我无法重现此行为。请编辑您的问题以提供演示此问题的简短代码示例。
当我创建一个JPanel并在其中放入一些内容时,当鼠标移动到JPanel的子组件上时,JPanel不会获得mouseExit。我猜你已经为孩子们添加了MouseListeners。