views:

126

answers:

2

I just learned (the hard way) that Java Components can only have one DropTarget. No sweat, I said, I'll just add another DropTargetListener to that DropTarget--only to discover that DropTargets can only have one DropTargetListener!

I have two DropTargetListeners that listen for very different events (one handles things being dragged and dropped within the component, the other handles things from outside the component). Must I combine them into one giant DropTargetListener, or is there an elegant way to keep them separate?

+2  A: 

If you don't find a satisfactory solution, you could use the Composite Pattern to create a DropTargetListener that has a list of child DropTargetListeners. Whenever one of its methods are called, it would iterate over its list of listeners and invoke the same method. That would allow you to hand a single DropTargetListener to the Component but still have multiple DropTargetListeners called.

SingleShot
This is exactly the kind of elegant solution I was looking for. Thank you!
Amanda S
Shoot, this doesn't actually work. If the first DropTargetListener rejects the drag event, it will not make it through to the other listeners. I tried to fix this by duplicating the drag event and passing a different copy to each listener, but that caused its own problems, like listeners recieving drop events when they shouldn't be, etc.
Amanda S
Maybe this is why Java does not allow multiple drop listeners per component.
Rafał Dowgird
LOL. Indeed. I still wish they had applied more intelligence to the problem--it's a significant limitation!
Amanda S
It is hard to come up with an intelligent universal solution. I edited my answer to include a "best effort" hack.
Rafał Dowgird
+2  A: 

DropTarget is a unicast source, so you can add at most one DropTargetListener to it. I believe it should be a simple object that examines the source (inside/outside) of the thing being dropped and calls one of your DropTargetListeners depending on the result.

Edit: If you are hell bent on creating a "universal" solution, then you might try creating a wrapper event that passes method calls to the original event, but intercepts rejectDrop(), acceptDrop() (and maybe other methods that can cause trouble), then pass the wrapper to your listeners, until one accepts it. This assumes that the listeners recognize "good" events and act accordingly.

Rafał Dowgird