コンテナでさまざまなアプローチを試した後、成功せず、タイマーを使用することになりました。私のコンテナに、すでにマウスリスナーが必要な要素が含まれていることは役に立ちませんでした。
タイマーアプローチはまた、私が変更を短時間遅らせることができることを意味しました。(私の場合、ツリーノード(コンテナ)に追加のボタンを表示し、背景を変更します。)
コンテナのmouseEntered()で、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()
}
}
...
}