Eclipse RCP - Drag and Drop Subtleties

I spent several hours trying to work out why my applications drag and drop support would work for drag but no drop. Dragging and dropping between two views in the same plugin wouldn't work

Drag and Drop works on external targets but not internal!

After reading the documentation several times and  doing debug traces, which wasn't easy as putting breakpoints on a drag and drop operation resulted in the machine locking up (I kept a ssh session open to kill of eclipse when this happened without having to reboot the whole machine), I was at a loss. Then while doing some testing I accidentally dropped the drag operation onto Gnome's text editor and low and behold it worked. So clearly there was nothing wrong with the drap implementation so it must be in the drop target that the problem existed. When doing tests with the text editor I noticed that the drop cursor changed to include a + sign decorator. This wasn't happening when I dragged the folders over my view. I simply got a folder icon.

Sometimes repeating the same actions and expecting a different result can work :)

This got me thinking about something I read that the default drop operation in Eclipse is DND.DROP_MOVE. My view was setup to only accept DND.DROP_COPY only.  The text also talked about modifier keys. Personally I have never used modifier keys when dragging and dropping. I just drag and then drop. Pushing the ctrl key while dragging and dropping the folder on the target view got the missing + sign to show and it worked!

Drag and Drop in SWT default operation is DROP_MOVE

After pondering this for a while I remember reading that the drag operation can be 'ored' with a DND.DROP_DEFAULT that would then be used to change the default operation if needed. The only issue was that I was extending the ViewDropAdatper class which only required two methods to be implemented, validateDrop and performDrop, neither of which gave me a chance to interrogate the operation of change the default. But this was simple enough to solve by just overriding the dragOver function to do the check.

    @Override
    public void dragEnter(DropTargetEvent event) {
        if (event.detail == DND.DROP_DEFAULT) {
              if ((event.operations & DND.DROP_COPY) != 0) {
                    event.detail = DND.DROP_COPY;
              }
        }
        super.dragEnter(event);
    }

 

Works like a charm now.

Comments