API proposal: drag view

Pavel Safrata pavel.safrata at oracle.com
Tue Jan 15 10:49:03 PST 2013

There was no response to this part of my previous email:
Would it be sufficient if the controls contained getDefaultDragImage() 
method that users would explicitly call?

On 15.1.2013 19:41, steve.x.northover at oracle.com wrote:
> Got it.  You need to start drag and drop before you get a drag board. 
> Drag and drop is started in drag detect which takes a MouseEvent, not 
> a DragEvent.
> How are we going to allow tree and table to provide default drag images?
> Steve
> On 15/01/2013 1:06 PM, Pavel Safrata wrote:
>> Hi Steve,
>> I take it that you want it only for the drag start and you are not 
>> concerned about an inaccessible value during the rest of the gesture 
>> (we are not always the source so we don't always set the drag image). 
>> Still, how would you even access the dragboard in a different node 
>> than the one that started the DnD to call the getter if we provided 
>> it? I don't think we have a mechanism for one node starting DnD and 
>> another node altering the dragboard.
>> Thanks,
>> Pavel
>> On 15.1.2013 18:55, steve.x.northover at oracle.com wrote:
>>> Without a getter, the application has no idea whether a drag image 
>>> has already been set for them. Having a setter without a getter 
>>> generally makes no sense. Since we set the drag image, we can easily 
>>> return the image that we set.
>>> Steve
>>> On 15/01/2013 4:20 AM, Pavel Safrata wrote:
>>>> Hi Richard, Steve,
>>>> On 14.1.2013 20:51, steve.x.northover at oracle.com wrote:
>>>>> +1
>>>>> I'd like to see some example code where the tree and table set a 
>>>>> default image as part of the implementation of these controls. 
>>>>> Applications would get a reasonable image for free and be able to 
>>>>> override it as necessary.  Having and getter is necessary for this.
>>>> Is it? What will be done with it? User will get the image and 
>>>> programatically check if it looks good?
>>>> (please see my answers to Richard's comments below).
>>>>> BTW, the last time I looked, on Windows, when you set image 
>>>>> content, then you will get a drag image for free. This doesn't 
>>>>> happen on the Mac.  We should stop doing this on Windows.
>>>>> Steve
>>>>> On 14/01/2013 2:09 PM, Richard Bair wrote:
>>>>>> HI Pavel!
>>>>>> Overall great. I don't see why you can't have a getter. The only 
>>>>>> way to set the drag view is via an API we control so it seems 
>>>>>> pretty easy to implement the getter as well. 
>>>> No. DnD is an OS feature. You can drag data from native 
>>>> applications to FX. Is it possible on all systems to find out what 
>>>> did the native application use as drag image? I'm really not sure. 
>>>> Anybody has the knowledge?
>>>>>> You could either have a DragView class which encapsulates the 
>>>>>> node/image and the offsetX and offsetY, or you could just break 
>>>>>> it out into three properties on the DragBoard and save yourself 
>>>>>> the extra class.
>>>> If we are OK with the properties having value only during starting 
>>>> DnD and not during the rest of the gesture, then yes, this could be 
>>>> done. But I still don't see the value.
>>>>>> I think you should just have an image based dragImage property 
>>>>>> and dragImageOffsetX and dragImageOffsetY properties. We 
>>>>>> shouldn't by default put anything in as the drag image, except 
>>>>>> for a few UI controls. We'll want a ListView, TreeView, 
>>>>>> TableView, TreeTableView to automatically pre-populate the 
>>>>>> DragBoard before the onDragDetected code is called, so that those 
>>>>>> control give you a nice drag image for free but the developer is 
>>>>>> free to replace it or clear it as they see fit.
>>>> I don't think this is possible with the proposed API. The DragBoard 
>>>> instance doesn't exist until you start DnD in the DRAG_DETECTED 
>>>> handler, so you cannot really pre-populate it. Would it be 
>>>> sufficient if the controls contained getDefaultDragImage() method 
>>>> that users would explicitly call?
>>>>>> The developer could use the synchronous version of snapshot. But 
>>>>>> I think either snapshot should be fixed to be transparent by 
>>>>>> default instead of a white fill by default or add another 
>>>>>> snapshot method which produces a transparent fill by default.
>>>> True. Kevin, how easy/hard it would be to add such snapshot method?
>>>> Thanks,
>>>> Pavel
>>>>>> Basically:
>>>>>> source.setOnDragDetected(new EventHandler<MouseEvent>() {
>>>>>>      public void handle(MouseEvent event) {
>>>>>>          DragBoard db = source.startDragAndDrop(TransferMode.ANY);
>>>>>>          db.setContent(…);
>>>>>>          db.setDragImage(source.snapshot());
>>>>>>          db.setDragImageOffsetX(event.getX());
>>>>>>          db.setDragImageOffsetY(event.getY());
>>>>>>          event.consume();
>>>>>>      }
>>>>>> }
>>>>>> Maybe also have a convenience method on DragBoard:
>>>>>>      db.updateDragImage(node, x, y);
>>>>>> which then just calls the 3 setters as appropriate.
>>>>>> Richard
>>>>>> On Jan 13, 2013, at 11:59 PM, Pavel 
>>>>>> Safrata<pavel.safrata at oracle.com>  wrote:
>>>>>>> Hello,
>>>>>>> this is a proposal of an API allowing to specify the image 
>>>>>>> floating with mouse cursor during a drag&drop operation.
>>>>>>> Jira: http://javafx-jira.kenai.com/browse/RT-14730
>>>>>>> I propose to add two methods to DragBoard:
>>>>>>> setDragView(Image image, double offsetX, double offsetY)
>>>>>>> setDragView(Node node, double offsetX, double offsetY)
>>>>>>> The first one simply uses the given image for the drag view with 
>>>>>>> the offsetX and offsetY specifying cursor position over the 
>>>>>>> image. The second one renders the given node to an image and 
>>>>>>> uses the result (the coordinates being in the node's local space).
>>>>>>> The typical usage will look like this:
>>>>>>>         sourceNode.setOnDragDetected(new 
>>>>>>> EventHandler<MouseEvent>() {
>>>>>>>             public void handle(MouseEvent event) {
>>>>>>>                 Dragboard db = 
>>>>>>> source.startDragAndDrop(TransferMode.ANY);
>>>>>>>                 ClipboardContent content = ...
>>>>>>>                 db.setContent(content);
>>>>>>>                 db.setDragView(sourceNode, event.getX(), 
>>>>>>> event.getY()); // that's it
>>>>>>>                 event.consume();
>>>>>>>             }
>>>>>>>         });
>>>>>>> This API is meant for telling the operating system what visual 
>>>>>>> cues to provide, I don't think it is useful (and I'm not sure it 
>>>>>>> is even possible) to provide getters.
>>>>>>> There is a possibility to provide default drag view - if none of 
>>>>>>> those methods is called, the default drag view would be an image 
>>>>>>> of the drag gesture source. This should work nice most of the 
>>>>>>> times. However, it may cause inconveniences to some existing 
>>>>>>> apps - for instance a text editor node which puts the selected 
>>>>>>> text on the DragBoard - after updating FX the application starts 
>>>>>>> to show the entire editor in the drag view. For this reason I 
>>>>>>> think the default behavior should remain unchanged.
>>>>>>> Thanks,
>>>>>>> Pavel

More information about the openjfx-dev mailing list