I have a question about dragging and droping:
I can drop labels, text or icon. But I want to drag and drop a JPanel with all its components (Label, Textbox,..etc).
How can I do this ?
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
This solution works. Some cavets to start with.
I didn’t use the TransferHandler API. I don’t like it, it’s too restrictive, but that’s a personal thing (what it does, it does well), so this might not meet your expectations.
I was testing with BorderLayout. If you want to use other layouts, you’re going to have to try and figure that out. The DnD subsystem does provide information about the mouse point (when moving and dropping).
So what do we need:
A DataFlavor. I chose to do this because it allows a greater deal of restriction
A Transferable. Some kind of wrapper that wraps the data (our JPanel) up with a bunch of DataFlavors (in our case, just the PanelDataFlavor)
A “DragGestureListener”
For this, I created a simple DragGestureHandler that takes a “JPanel” as the content to be dragged. This allows the gesture handler to become self managed.
Okay, so that’s basics. Now we need to wire it all together…
So, in the panel I want to drag, I added:
The reason for using the add/remove notify in this way is to keep the system clean. It helps prevent events from been delivered to our component when we no longer need them. It also provides automatic registration. You may wish to use your own “setDraggable” method.
That’s the drag side, now for the drop side.
First, we need a DropTargetListener:
Finally, we need to register the drop target with interested parties… In those containers capable of supporting the drop, you want to add
Personally, I initialise in the addNotify and dispose in the removeNotify
Just a quick note on addNotify, I have had this been called a number of times in succession, so you may want to double-check that you haven’t already set up the drop targets.
That’s it.
You may also find some of the following of interest
http://rabbit-hole.blogspot.com.au/2006/05/my-drag-image-is-better-than-yours.html
http://rabbit-hole.blogspot.com.au/2006/08/drop-target-navigation-or-you-drag.html
http://rabbit-hole.blogspot.com.au/2006/04/smooth-jlist-drop-target-animation.html
It would be waste not to check them, even if just out of interest.
2018 Update
So, after 4 years since the original code was written, there seems to have been some changes into how the API works, at least under MacOS, which are causing a number of issues .
First
DragGestureHandlerwas causing aNullPointerExceptionwhenDragSource#startDragwas been called. This seems to be related to setting the container’sparentreference tonull(by removing it from the parent container).So, instead, I modified the
dragGestureRecognizedmethod to remove thepanelfrom the parent AFTERDragSource#startDragwas called…I also modified the
DragGestureHandler#dragDropEndmethodAnd
DropHandler#dropIt’s important to note that these above modifications probably aren’t required, but they existed after the point I got the operations to work again…
Another issue I came across was a bunch of
NotSerializableExceptionsI was required to update the
DragGestureHandlerandDropHandlerclasses…Runnable example…
DragPaneDropPaneThe
DragGestureHandler,DropHandler,PanelDataFlavorandPanelTransferableclasses remain the same, except for the changes I’ve mentioned above. All these classes are standalone, external classes, otherwise it causes additionalNotSerializableExceptionproblemsNotes
It’s possible that having the
DragGestureHandlermanaged by the same component which is been dragged could be causing the over all issues, but I don’t have the time to investigateIt should be noted that, I don’t prompt nor condone manipulating components in this way, as it’s way to easy to end up in situations where a solution might work today, but won’t work tomorrow. I prefer to transfer state or data instead – much more stable.
I had tried a dozen other examples based around the same concept presented in the original answer which simply transferred state and they all worked without issue, it was only when trying to transfer
Components it failed – until the above fix was applied