我已经实现了一个简单的鼠标侦听器,每当鼠标进入组件(jpanel)时,背景颜色会发生变化,并且每当鼠标离开时它都会恢复。这有一些问题:

  • 有时鼠标移动得如此之快,以至于 mouseexit 事件未开除
  • 如果我的组件有子,当鼠标移至孩子时,它会触发 mouseexit
  • 如果我迅速将鼠标移到孩子身上, 鼠标 事件未开除

我猜这对于秋千退伍军人来说很容易。对于如何解决这个问题,有任何的建议吗?我很想不要使用计时器等...

有帮助吗?

解决方案

如果我将鼠标迅速移至孩子,则不会解雇Mexenter事件

我从未见过这种情况发生,但是如果这是一个问题,那么您可以处理Mousemped而不是重置背景。

如果我的组件有子,当鼠标移动到子女时,它会触发mouseexit

使用以下测试,只有在离开组件界限时才会执行代码:

public void mouseExited(MouseEvent e) 
{
    if (! getVisibleRect().contains(e.getPoint()) )
    {
        setBackground(...);
    }
}

其他提示

有许多解决方案:

  • 将鼠标侦听器添加到儿童组件中。同样,在添加和删除组件时,也要添加和删除侦听器。不幸的是,添加鼠标听众不满意鼠标事件(可怕的设计)。
  • 在顶部加一个玻璃窗格。这是丑陋的,事件的转发总是引起问题。
  • 添加一个 AWTEventListener 默认 Toolkit 并过滤您感兴趣的事件。不幸的是,这需要安全许可。
  • 推动自定义 EventQueue 和过滤事件。这需要安全许可,将applet和webstart/jnlp应用程序获取该权限。

尝试在容器上尝试了各种方法后,我最终使用了 计时器. 。我的容器包含已经需要鼠标侦听器上的元素没有帮助。

计时器方法还意味着我可以在短时间内延迟更改。 (就我而言,我在树节点(容器)中显示其他按钮,并更改背景。)

鼠标() 在容器上, 计时器 是创建(如果还没有的话),每260毫秒重复一次。在计时器的每个呼叫上,它确定鼠标是否在容器内部。如果是这样,它是第一次发出鼠标的信号。如果没有,它向非小鼠发出信号并停止计时器。

在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()
    }
  }
...
}

我不能复制这种行为。请编辑您的问题,提供一个简短的代码示例来证明问题。

当我创建jpanel并将某些内容放入其中时,当鼠标移动Jpanel的子组件时,JPANEL不会得到Mouseexit。我猜想您已经向孩子们添加了Mouselisteners。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top