我有一个节点,我想实现拖放(这个对象是源而不是目标)。我还希望对象能够随着鼠标光标移动。我设法做到了这两件事,但不是同时做到的。
看来setOnDragDetected
和setOnMouseDragged
不能很好地协同工作。考虑一个具有以下处理程序的节点:
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
的父,但我想要的行为是在节点,因为这是它真正应该在哪里。
你把两件事混在一起了。简而言之,当您调用startDragAndDrop
方法时,系统切换到拖放模式,Java停止将MouseEvent
传递给rect
。
MouseEvent文档中有一节"拖动手势",解释了三种类型的拖动手势。下面是一个简短的总结:
- 简单的按下-拖放-释放-当检测到拖放时,Java继续向检测到拖放的节点传递
MouseEvents
。 - 完整的按-拖-放-你可以在你用
setOnDragDetected
设置的处理器中调用startFullDrag
。然后Java也开始传递MouseDragEvents
到其他节点(潜在的手势目标)。 - 平台支持的拖放-如果在
OnDragDetected
处理程序中调用startDragAndDrop
, Java将停止交付MouseEvents
,并开始交付DragEvents
。用于与其他应用程序进行拖放交互。
我不清楚你想要实现什么,但只要你不想拖拽应用程序之外的东西,尝试使用startFullDrag
代替。
此外,进一步查看DragEvent和MouseDragEvent文档可能会有所帮助。