2016-11-17 63 views
2

我有一个节点,我想实现拖放(此对象是源不是目标)。我也希望对象随鼠标光标一起移动。我设法做到了这两个,但不是在同一时间。如何在拖放操作中执行代码?

看起来setOnDragDetectedsetOnMouseDragged不能很好地协同工作。考虑一个节点具有以下处理:

import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.input.ClipboardContent; 
import javafx.scene.input.Dragboard; 
import javafx.scene.input.TransferMode; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class Example extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception { 

     Rectangle rect = new Rectangle(20, 20); 
     rect.setOnMousePressed(e -> System.out.println("Pressed")); 
     rect.setOnMouseDragged(e -> System.out.println("Dragged")); 
     rect.setOnDragDetected(e -> { 
      System.out.println("Detected"); 
      ClipboardContent content = new ClipboardContent(); 
      content.putString("something"); 
      Dragboard db = rect.startDragAndDrop(TransferMode.ANY); 
      db.setContent(content); 
     }); 
     Group subGroup = new Group(rect); 

     Scene scene = new Scene(subGroup, 100, 100); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 

     Example.launch(args); 
    } 
} 

现在点击鼠标的节点上,然后移动鼠标。这是输出:

Pressed 
Dragged 
Dragged 
Dragged 
Dragged 
Dragged 
Dragged 
Detected 

一旦检测到拖动,MouseDragged处理程序停止。

我如何实现我所描述的?我注意到的一件事可能是我可以使用onDragOver作为父项,但我希望行为在节点中,因为那就是它应该在的位置。

+0

我根本没有观察到这种行为;检测到拖动手势后,onMouseDragged处理程序继续进行报告。你应该创建一个[MCVE]并且[编辑]你的问题来包含它。 –

+0

@James_D对不起。这里是代码。它与我想的拖板有关。 – Mark

回答

0

你在这里混合两件事。简而言之,当您调用startDragAndDrop方法时,系统将切换到拖放模式,并且Java停止将MouseEvent传送到rect

MouseEvent documentation有一个“拖动手势”部分,它解释了三种拖动手势类型。这里只是一个简短的总结:

  • 简单按拖拽释放 - 当检测到拖拽的Java将继续提供MouseEvents到检测拖动的节点。
  • 完全按压 - 拖放 - 您可以在setOnDragDetected设置的处理程序中调用startFullDrag。然后,Java也开始向其他节点(潜在手势目标)传递MouseDragEvents
  • 平台支持的拖放 - 如果您在OnDragDetected处理函数中调用startDragAndDrop,则Java将停止传递MouseEvents并开始交付DragEvents。这用于与其他应用程序的拖放交互。

我不清楚你想达到什么目的,但只要你不想在应用程序外面拖动某些东西,请尝试使用startFullDrag来代替。

另外,进一步查看DragEventMouseDragEvent文档可能会有帮助。

+0

我只需要我的应用程序中的事件。如果我使用'startFullDrag',目标节点不会响应'OnDragEntered'并退出。有些东西需要检查拖放操作是否正在发生,正在进入/离开他们的空间并根据内容做出反应 - 如果它是有效的。这我只能用'startDragAndDrop'来完成。 – Mark

+0

@Mark如果您使用'startFullDrag',则需要在目标上设置OnMouseDragEntered处理程序,而不是OnDragEntered。 – FelixRabe

+0

是的,但鼠标拖动处理程序的功能与D&D处理程序不同。例如:'OnDragDone'允许在拖动结束时对源进行操作,但没有与“onMouseDragDone”等效的内容。此外,鼠标指针不会改变,以指示放置目标是否有效,就像它与D&D一样。 – Mark