views:

260

answers:

5

Hello!

Can I add a listener (let's say MouseAdapter) to a Swing component and all it's internal decoration components?

So that when a JInternalFrame is moved by the mouse (by dragging its window title bar), it would give me following events:

  • mousePressed event,
  • mouseDragged event,
  • mouseReleased event.

Currently, I receive none of the above events when dragging JInternalFrame.

I hope there is some standardized solution, but I couldn't find any.

EDIT:
Some people suggest using ComponentListener, but that wouldn't do for me. I need to know, when the user stops dragging (mouseReleasedEvent), not when the component moves.

A: 

You should probably use a MouseMotionListener instead of a MouseListener.

Bombe
MouseAdapter implements both, and I add it usingaddMouseListener(...) and addMouseMotionListener(...)
ivan_ivanovich_ivanoff
A: 

In the JInternalFrame API documentation, it says:

Generally, you add JInternalFrames to a JDesktopPane. The UI delegates the look-and-feel-specific actions to the DesktopManager object maintained by the JDesktopPane.

Maybe you should add your listener to the JDesktopPane.

micro
A: 

MouseListener/MouseMotionListener wont detect when dragging a JInternalFrame. Your best bet here to detect movement is using a ComponentListener on the JInternalFrame itself.

willcodejavaforfood
The ComponentListener fires the event "componentMoved", but I need to know when the user begin and end the dragging operation. The user could let the mouse button pressed but don't move the commponent. ComponentListener wouldn't tell me that the mouse button is still pressed.
ivan_ivanovich_ivanoff
I realise that, but not quite sure how you would acomplish that so this was the best I could do. Out of curiosity why do you need to know this?
willcodejavaforfood
+1  A: 

Yes, you can add a listener to all a container's components. getComponents and add the listener. You should be able to manage to do this recursively. You can also use ContainerListener to check for adding and removing components.

However, MouseListener and MouseMotionListener behave strangely in that the event normally bubbles up to the parent, but does not do so if a listener is present (how is that for hopeless design?).

Your choices are:

  • Recursively adding listeners (bad, see above)
  • Adding listeners to specific components (fragile)
  • Adding a "glass pane" (a messy hack)
  • Adding an AWTEventListener to Toolkit (requires permissions)
  • Pushing an EventQueue and checking through events (doesn't work of Opera and Safari apparently; stops system copy-and-paste and applet dragging from working)
  • Use ComponentListener?
Tom Hawtin - tackline
Tried: glass pane doesn't receive necessary events. I think I'm going write own draggable component (already done once)
ivan_ivanovich_ivanoff
A glass pane on the contents area of the internal frame (obviously) wont work.
Tom Hawtin - tackline
Ah, sorry, you mean glass pane of the parent of JInternalFrame.Why it's a messy hack?
ivan_ivanovich_ivanoff
Glass panes are always a hack. All that event forwarding. Eurgh. In 1.6, popup were moved from glass panes (which caused a few issues) to awt event listener.
Tom Hawtin - tackline
A: 

I found out how it could be done, but something tells me, it's a dirty hack ;)

Well, it works, but who can give me the guarantee that it works everywhere?

// ctor goes here {

InternalFrameUI thisUI = getUI();
((BasicInternalFrameUI) thisUI).getNorthPane()
    .addMouseMotionListener(new MyMouseListener());

// }

NorthPane turns out to be the window title bar.

ivan_ivanovich_ivanoff