B4J Library jDragAndDrop2 - Drag and Drop

This library is an update to Andrews jDragandDrop to take advantage of the DragBorad.DragView available in JavaFX8. This allows displaying a graphic next to or behind the mouse cursor while dragging items.

It's not quite a drop in replacement, but I tried to make it as close as possible.

The differences are:
  1. The DragAndDrop class needs to be initialized with the Callback module.
  2. The Transfer Mode does not support strings, it needs to be a TransferMode array, which are available as variables from the TransferMode static class.
  3. The e.AcceptTransferMode call has changed to e.AcceptTransferModes.
  4. There are two additional SetDragModeAndData methods to cater for setting the DragView.
  5. I have exposed most of the Dragboard methods which make it easier to select the data you want to accept, and get the results from the dragboard, and most of the DragEvent methods. Existing code should work as is.
  6. If you use sender to get the current EventSource (as opposed to the GestureSource) you will need to change it from sender to e.GetEventSource
The demo shows drag and drop from within the app, and from outside it for text and images.

Issues:
The only issue I found, and it may be a 'feature'. Is that if an image is being dragged, a copy of that image is used in place of whatever is set in the dragview. I would have preferred to be able to set a thumbnail, but it doesn't appear to work like that.​

It's written as 4 code modules, you can compile it to a library if you prefer.
Please let me know if you find any problems with it.

For a b4xlib, see Erel's implementation in post #3

Enjoy.
 

Attachments

  • jDragandDrop2.zip
    35.2 KB · Views: 858
Last edited:

moster67

Expert
Licensed User
Longtime User
Only saw this one now...it could have saved me time.
Thanks Steve.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've packaged your library as a b4x lib and also added a simple example of dropping text files:

drag.gif


The example project is attached.

Example of dragging files from the app: https://www.b4x.com/android/forum/threads/dragging-images-text-to-other-apps.129899/post-817145
 

Attachments

  • DragAndDrop2.b4xlib
    6.5 KB · Views: 738
  • Example.zip
    2.2 KB · Views: 642
Last edited:

LucaMs

Expert
Licensed User
Longtime User
I still think that we "need" a B4X forum; I found this very useful B4Xlib... "casually".

Also, I would change its name to B4XDragAndDrop (or B4XDragDrop).
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
Such posts only add clutter. -Your comment has nothing to do with this thread.
I don't think anyone who reads my post loses orientation.

Also note that this is a B4J only library.
I was referring to your b4xlib in this thread; then it also creates clutter, since it is in a thread for B4J libraries (no, I don't think this that creates clutter but only that whoever finds this thread will be content to read the first post without knowing that there is also your version b4xlib).

However, it is certainly true that I have to train myself not to write O.T.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I was referring to your b4xlib in this thread; then it also creates clutter, since it is in a thread for B4J libraries
That's wrong. b4xlibs can be cross platform. It doesn't mean that all b4xlibs are cross platform.
If you try to add this library to B4A or B4i it will show an error message because the "Supported Platforms" field is set to B4J.
 

LucaMs

Expert
Licensed User
Longtime User
This is an old thread, I know, but what I'm about to write is so useless 😁 that I can write it here too.

In a very small test project, just to drag text lines from a Windows sw to a B4J TextArea, I used the Erel's B4Xlib and it works perfectly, so I made the changes to the project I am developing and... the dropped event does not fire.

So I jumped through hoops to understand the reason and couldn't find it.
After many studies and attempts I have even taken the few parts that make up the test project and I have inserted them so as they are in the main project; nothing, they don't work in my "main project".

At that point I thought there was something strange in the Main Form of the main project, which opens a dialog form and in this second the dragging should work but I didn't see any oddities.

After hours of going crazy, even comparing the generated Java code (of the Main form) I wanted to do one last test: exclude the B4Xlib and directly import Steve's 4 classes. Here, now it works.

I don't know if the 4 classes in the B4Xlib have been changed; if so, that would be the cause, otherwise... I just don't understand.

Anyway, problem solved (but I'll have to remember it, which is not easy)
 

LucaMs

Expert
Licensed User
Longtime User
Are you running in debug mode?
Yes.

Anyway, changing the Erel's manifest from:
B4X:
Version=1.00
Supported Platforms=B4J
DependsOn=JavaObject

to:
B4X:
Version=1.00
Supported Platforms=B4J
B4JDependsOn=JavaObject

the B4Xlib works both on the test project and the "main one" (still in debug mode).
 

LucaMs

Expert
Licensed User
Longtime User
Anyway, changing the Erel's manifest from:
No, that wasn't the problem; both manifest work.

Maybe it works now, even with the Erel's manifest, because I've made a copy of the entire project folder (I haven't changed anything in the project).

I need to read your tip, Steve.
 

LucaMs

Expert
Licensed User
Longtime User
I'm going crazy to find that problem!

Now the main project works, with the b4xlib unmodified and in debug mode, that is exactly as tried for hours previously.

Perhaps the only different thing (Perhaps, because after so many attempts, I got lost) the problem was the "meta" file, but it seems strange to me.

Well, solved, anyway.
 

alirezahassan

Active Member
Licensed User
i have an error
Error occurred on line: 48 (Dragboard)
java.lang.IndexOutOfBoundsException: Index: 0
at java.base/java.util.Collections$EmptyList.get(Collections.java:4481)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:122)
at com.schoolaghamostafa.marvarin.m_azmoon_souals$ResumableSub_DropTarget_Text_DragDropped.resume(m_azmoon_souals.java:2011)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:47)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:108)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:95)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:42)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:153)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:102)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:95)
at anywheresoftware.b4a.keywords.Common$3.run(Common.java:1103)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
 

stevel05

Expert
Licensed User
Longtime User
It's impossible to tell without seeing your code. It seems likely that the dragboard is not initialized correctly, but no idea how or why.
 

alirezahassan

Active Member
Licensed User
It's impossible to tell without seeing your code. It seems likely that the dragboard is not initialized correctly, but no idea how or why.
thank you for replying
All my code is similar to the example.
Until a few days ago, it worked without any problems
B4X:
Sub DropTarget_Text_DragDropped(e As DragEvent)
    Try
        Log(e.GetDragboard.GetFiles)
        uploudFile(File.GetFileParent(e.GetDragboard.GetFiles.Get(0)),File.GetName(e.GetDragboard.GetFiles.Get(0)),"Text")
        e.SetDropCompleted(True)
    Catch
        Log(LastException)
    End Try
End Sub

log code for Log(e.GetDragboard.GetFiles)
(EmptyList) [] ->>
log for uploudFile(...
(IndexOutOfBoundsException) java.lang.IndexOutOfBoundsException: Index: 0

B4X:
Private DragAndDrop_Text As DragAndDrop
...
DragAndDrop_Text.Initialize(Me)
DragAndDrop_Text.MakeDragTarget(TXT_Text, "DropTarget_Text")
...
Sub DropTarget_Text_DragEntered(e As DragEvent)
    If IsValidDropEvent(e) Then
        TXT_Text.SetColorAndBorder(xui.Color_White, 4dip, xui.Color_Green, 0)
    Else
        TXT_Text.SetColorAndBorder(xui.Color_White, 4dip, xui.Color_Red, 0)
    End If
End Sub

Sub DropTarget_Text_DragExited(e As DragEvent)
    TXT_Text.SetColorAndBorder(xui.Color_White, 0, 0, 0)
End Sub

Sub DropTarget_Text_DragOver(e As DragEvent)
    If IsValidDropEvent(e) Then e.AcceptTransferModes(TransferMode.COPY)
End Sub

Sub DropTarget_Text_DragDropped(e As DragEvent)
    Try
        Log(e.GetDragboard.GetFiles)
        uploudFile(File.GetFileParent(e.GetDragboard.GetFiles.Get(0)),File.GetName(e.GetDragboard.GetFiles.Get(0)),"Text")
        e.SetDropCompleted(True)
    Catch
        Log(LastException)
    End Try
End Sub

Sub IsValidDropEvent(e As DragEvent) As Boolean
    If e.GetDragboard.HasFiles Then
        Dim files As List = e.GetDragboard.GetFiles
        If files.Size = 1 Then
            Dim filename As String = files.Get(0)
            If filename.ToLowerCase.EndsWith(".png") = True Or filename.ToLowerCase.EndsWith(".jpg") = True Then
                Return True
            Else
                Return False
            End If
        End If
    End If
    Return False
End Sub
 

stevel05

Expert
Licensed User
Longtime User
Are you running in debug mode? Does it work or give a different error line number in release mode?
 

stevel05

Expert
Licensed User
Longtime User
Can you zip and post the project?

As it stands, the code looks correct to me. The drag is only allowed (through the e.AcceptTransferModes(TransferMode.COPY) statement) if there is one file on the clipboard and it is a jpg or png file. But when it is dropped the error suggests that there are no files on the clipboard.

Have you set more than one drag target?
 

alirezahassan

Active Member
Licensed User
I defined in a module code several library times. Is it possible to make a problem? But previously worked right.
My project is big. and i can't send my project here.

Have you set more than one drag target? I'm dragging a png file.
 

stevel05

Expert
Licensed User
Longtime User
Sorry, I'm not sure what you mean. If you mean that you have defined the same target several times, then it could well cause problems.
 
Top