views:

65

answers:

3

It is a bit strange for me but JPanel does not generate MouseEvents when cursor is on child components: JTextField and JToolBar but it generates MouseEvents when cursor is on JLabel. Could someone explaind me why? Is there any way to force JPanel to generate events even if mouse is on child components?

+1  A: 

you may want to have the child components (JTextField, JToolBar, etc) listen for the mouse events from the jpanel and/or forward the mouse events to the child components.

Jill Renee
+1 I think forwarding is the right idea, but @guest may want to forward events from the child component to the parent `JPanel`, as suggested in this example: http://stackoverflow.com/questions/2159803
trashgod
+1  A: 

Could someone explain why?

Component mouse events are handled by processMouseEvent(), which says

Mouse events are enabled when one of the following occurs:

  • A MouseListener object is registered via addMouseListener.
  • Mouse events are enabled via enableEvents.

You can use getMouseListeners() to see the difference.

trashgod
+1, Cool, I didn't know a getMouseListeners() method existed. I've always used the generic getListeners(...) method. This will make life a little easier in the future.
camickr
@camickr: Interesting; I didn't know `getListeners()` supported a class literal type-token, _à la_ `EventListenerList`. Sadly, the +1 seems to have gone missing. :-)
trashgod
Oops... the +1 has been found.
camickr
+2  A: 

The event dispatcher will forward mouse events to the listeners registered to the component that is returned by the package-level getMouseEventTarget method in Container. This will be called on your JFrame, and, as the JavaDoc indicates, it:

Fetchs the top-most (deepest) lightweight component that is interested in receiving mouse events.

The event dispatcher then takes this top-most component (your JTextField, for example) and sends events to all of its listeners only. They do this in order to avoid having to broadcast these events to all of the components that may be layered within a Swing container. MouseEvents, as you can imagine, are very chatty, what with all of the mouseEntered, mouseDragged, and mouseMoved events that are dispatched for all of the MouseListener and MouseMotionListener implementations potentially out there. The processing to find all listeners and then fire events to all of them in the hierarchy would be time consuming.

The assumption is also that for classes like JTextField and JButton, etc., the default mouse handling is all that one would need. If you want to handle mouse actions differently (ie, changing color on a mouseEntered/mouseExited), you can add a MouseListener to these widgets as you need to.

For your processing, I would suggest simply adding your JPanel as a MouseListener to your top level components if you need to handled these events.

akf
+1 Interesting; `getMouseEventTarget()` has _package-private_ (no explicit modifier) access in `java.awt`, but most IDEs allow browsing the source.
trashgod