views:

757

answers:

3

Hi,

I've implemented a simple mouse listener where the background color changes whenever the mouse enters the component (a JPanel), and it reverts back whenever the mouse leaves. This has some problems:

  • Sometimes the mouse moves so quick that the mouseExit event is not fired
  • If my component has childs, when the mouse moves to the childs it triggers the mouseExit
  • If I move the mouse over to the childs quickly, the mouseEnter event is not fired

I'm guessing this is an easy one for Swing veterans. Any suggestions on how to fix this? I'd love not to use timers and such...

+1  A: 

There are a number of solutions:

  • Add mouse listeners to the child components. Also container listeners, to add and remove listeners as components are added and removed. Unfortunately adding mouse listeners upset bubbling up of mouse events (hideous design).
  • Add a glass pane over the top. This is mighty ugly, and forwarding of events always causes problems.
  • Add an AWTEventListener to the default Toolkit and filter through for the events you are interested in. This unfortunately requires a security permission.
  • Push a custom EventQueue and filter events. This requires a security permission, put applets and WebStart/JNLP applications get that permission anyway.
Tom Hawtin - tackline
I've tried the glass pane with no avail. Can I apply glass panes to simple JPanels? I thought you could only apply that to JFrames.Since I have multiple JPanels, I really need to apply the glass pane to each one of them.
Miguel Ping
A: 

I can't reproduce this behavior. Please edit your question to provide a short code sample that demonstrates the problem.

When I create a JPanel, and put something in it, the JPanel does not get mouseExit when the mouse moves over a child component of the JPanel. I'm guessing that you've added MouseListeners to the children.

Jonathan Feinberg
Yes, you are right. I tried adding mouse listeners to the children.
Miguel Ping
+2  A: 

If I move the mouse over to the childs quickly, the mouseEnter event is not fired

I've never seen this to happen, but if it is an issue then you can handle mouseMoved instead to reset the background.

If my component has childs, when the mouse moves to the childs it triggers the mouseExit

Use the following test and the code will only be executed when you leave the components bounds:

public void mouseExited(MouseEvent e) 
{
    if (! getVisibleRect().contains(e.getPoint()) )
    {
     setBackground(...);
    }
}
camickr
If you move the pointer from outside to a contained child (with a mouse listener) then a mouse listener on the parent container will not get fired. Move it slowly over a border region and it will.
Tom Hawtin - tackline
I've used a mix of your technique and Tom Hawtin's. Unfortunately only one of you can get the right answer. Thanks all.
Miguel Ping