Starting a system drag on a mouseExited event

Swing’s drag-and-drop implementation is pretty straightforward for the common cases—if you’re working with standard components, you might not have to do any work at all to get basic drag-and-drop support. However, once you get to the point of wanting to do interesting nonstandard things, it’s easy to get tangled up in the web of interrelated UI classes, many of which can’t just be constructed.
Case in point: in certain parts of my application, I’d like item dragging to be rendered by my component up until the point at which the cursor crosses the component’s boundary. It’s simple to start a system drag when at the point at which the user clicks the cursor on an item—but I want the system drag to start only when the component gets a mouseExited() during an in-component drag. After a bit of experimentation, I found that I could accomplish this using a custom, somewhat corrupt DragGestureRecognizer (application-specific code indicated by $dollar signs$):
private class ExitDragGestureRecognizer
extends DragGestureRecognizer {
public ExitDragGestureRecognizer(Component comp) {
super(DragSource.getDefaultDragSource(), comp);
}
public synchronized int getSourceActions() {
return DnDConstants.ACTION_COPY_OR_MOVE;
}
protected void registerListeners() {}
protected void unregisterListeners() {}
public void setEvent(InputEvent e) {
resetRecognizer();
appendEvent(e);
}
}
private ExitDragGestureRecognizer dgr =
new ExitDragGestureRecognizer($myPanel$);
Then, in the component’s attached MouseListener, the following code transfers from a local to a system drag when the cursor hits the component boundary:
public void mouseExited(MouseEvent e) {
if ($inLocalDrag()$) {
Transferable trans = $getDragTransferable()$;
DragSource source = DragSource.getDefaultDragSource();
DragGestureEvent event =
new DragGestureEvent(dgr, DnDConstants.ACTION_COPY,
$localDragStartPoint$, Collections.singletonList(e))
dgr.setEvent(e);
source.startDrag(event, DragSource.DefaultCopyDrop,
trans, null);
$endLocalDrag()$;
}
}
In my testing, this seemed to work under J2SE 1.4+ on Windows XP and Mac OS X 10.3.7. It’s really not all that difficult, but the only way I was able to figure it out was just by guessing at calls and seeing where they failed. If anyone knows of a good in-depth Swing reference that talks addresses this sort of thing, please let me know.
August 31st, 2007 at 12:08 am
[…] That is exactly how creeping incrementalism works in the real world of social and political change. Keep this analogy in mind as you read further.
For example, we all bleat on and thump our chests at the flacid criminal justice system, and wonder how it got to the state of impotence it’s apparently in, but do we stop and ask ourselves how it got to the point to which it has gotten? These ridiculous sentences for violent/repeat offenders seem contrary to our common sense, yet here we sit staring at it right before our eyes. It didn’t just happen overnight. It took years of gradual change (for now I’ll set aside my interpretaion of the specific mechanisms and ideologies at play), and we can’t believe it’s happening even while it’s happening. It can’t all be attributed to apathy, for surely a lot of people still vote; and not many (if any at all) voted specifically for these changes to occur or the legislation that made the situation possible.
by gsubspamCarma1186990996[…]