API proposal: drag view

steve.x.northover at oracle.com steve.x.northover at oracle.com
Tue Jan 15 11:03:27 PST 2013

I don't understand why it only works during drag detection.  We set the 
Java object in a field and we return that field.  Do you mean that 
setting the image outside of drag detect will not update the image that 
is used by the operating system?  I understand that this is most likely 
a restriction.


On 15/01/2013 1:56 PM, Pavel Safrata wrote:
> Richard,
> you're right, this could work. And the getter (or a boolean 
> hasDragImage()) could be used in this case. So are we OK with a getter 
> that works only during drag detection?
> Thanks,
> Pavel
> On 15.1.2013 19:46, Richard Bair wrote:
>> I assumed the Tree / Table could override this method and configure 
>> the drag board int he startDragAndDrop call itself?
>> On Jan 15, 2013, at 10:41 AM, 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