拖放事件最主要有以下几个:
onDragDetected、onDragOver、onDragEntered、onDragDropped、onDragExisted、onDragDone
这几个事件分别的触发点和作用或者区别如下:
onDragDetected
:这个方法是当用户在可以接受拖放的目标区域上按下鼠标按钮时触发。这并不意味着拖动已经开始,只是表示拖放的准备工作已经就绪。通常在这个方法中,你会开始拖动操作。onDragOver
:这个方法是当用户正在把一个拖动操作"拖过"一个目标区域时触发。换句话说,当用户按下鼠标并移动鼠标到目标区域上方时,这个方法就会被调用,相当于悬停在目标区域上方,会不断触发。通常在这个方法中,你可以决定目标区域是否接受这个拖放操作。onDragDone
:这个方法在拖放操作完成时被调用。这通常发生在用户放下被拖动的对象后,系统会向目标区域发送一个“拖放完成”的事件,onDragDone
方法就是用来处理这个事件的。在onDragDone
方法中,你通常可以进行一些清理工作,比如取消拖放效果、更新数据等。onDragDropped
:这个方法在拖动的对象被放进入到目标区域上时触发。这个事件表示拖放操作的目标已经达到,用户已经把被拖动的对象放在了目标区域上。在onDragDropped
方法中,你可以处理被拖动的对象和目标区域之间的数据交换等操作。onDragEntered
:当拖动的对象进入一个新的目标区域时触发。这意味着当用户把被拖动的对象从一个位置移动到另一个位置,并覆盖一个新的区域时,这个方法就会被调用。在这个方法中,你可以添加进入目标区域时的特殊效果或者处理逻辑。onDragExited
:当拖动的对象离开一个当前的目标区域时触发。这意味着当用户把被拖动的对象从一个位置移动到另一个位置,离开当前覆盖的区域时,这个方法就会被调用。在这个方法中,你可以添加退出目标区域时的特殊效果或者处理逻辑。
各事件区别:
onDragDetected
在开始拖动前被触发调用;
OnDragEntered
在拖放操作进入目标节点时触发;
onDragOver
在拖动过程中,当鼠标在目标区域上移动时被调用,即悬停在目标区域上时触发;
onDragDropped
则表示被拖动的对象被放在了目标区域上时触发;
onDragDone
表示拖放的整个过程已经结束;
OnDragExited 移动出目标区域时被触发
。
示例代码如下:
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class TestApplication extends Application {
@Override
public void start(Stage primaryStage) {
//拖放至少有两个区域,一个是源区域,一个是目标区域
TabPane sourceTabPane = new TabPane();
TabPane targetTabPane = new TabPane();
BorderPane root = new BorderPane();
root.setLeft(sourceTabPane);
root.setRight(targetTabPane);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
// 在源TabPane中添加一些初始的Tab
Tab tab1 = new Tab("tabName1");
Tab tab2 = new Tab("tabName2");
Tab tab3 = new Tab("tabName3");
// 注意,在实践中,无id时拖放无法触发事件,需要有id有数据传送才会生效拖放
tab1.setId("tabId1");
tab2.setId("tabId2");
tab3.setId("tabId3");
sourceTabPane.getTabs().addAll(tab1, tab2);
targetTabPane.getTabs().addAll(tab3);
// 设置源sourceTabPane的拖放触发处理
sourceTabPane.setOnDragDetected(event -> {
System.out.println("sourceTabPane.setOnDragDetected===");
onDragDetected(sourceTabPane);
event.consume();
});
sourceTabPane.setOnDragOver(event -> {
System.out.println("==sourceTabPane.setOnDragOver");
if (event.getGestureSource() instanceof TabPane) {
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
sourceTabPane.setOnDragExited(event -> {
System.out.println("==sourceTabPane.setOnDragExited");
event.consume();
});
sourceTabPane.setOnDragDropped(event -> {
System.out.println("==sourceTabPane.setOnDragDropped");
Dragboard dragboard = event.getDragboard();
if (dragboard.hasString()) {
String tabId = dragboard.getString();
Tab dragTab = null;
for (Tab tab : targetTabPane.getTabs()) {
if (tab.getId().equals(tabId)) {
dragTab = tab;
}
}
if (dragTab != null) {
targetTabPane.getTabs().remove(dragTab);
sourceTabPane.getTabs().add(dragTab);
event.setDropCompleted(true);
}
}
event.consume();
});
sourceTabPane.setOnDragEntered(event -> {
System.out.println("==sourceTabPane.setOnDragEntered");
event.consume();
});
sourceTabPane.setOnDragDone(event -> {
System.out.println("==sourceTabPane.setOnDragDone");
event.consume();
});
// 设置targetTabPane的拖放事件处理
targetTabPane.setOnDragOver(event -> {
System.out.println("targetTabPane.setOnDragOver===");
if (event.getGestureSource() instanceof TabPane) {
//注意下面必须设置为MOVE,否则无法接收拖来的tab数据
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
});
targetTabPane.setOnDragDropped(event -> {
System.out.println("targetTabPane.setOnDragDropped===");
Dragboard dragboard = event.getDragboard();
if (dragboard.hasString()) {
String tabId = dragboard.getString();
Tab dragTab = null;
for (Tab tab : sourceTabPane.getTabs()) {
if (tab.getId().equals(tabId)) {
dragTab = tab;
}
}
if (dragTab != null) {
sourceTabPane.getTabs().remove(dragTab);
targetTabPane.getTabs().add(dragTab);
event.setDropCompleted(true);
}
}
event.consume();
});
targetTabPane.setOnDragDetected(event -> {
System.out.println("==targetTabPane.setOnDragDetected");
onDragDetected(targetTabPane);
event.consume();
});
targetTabPane.setOnDragExited(event -> {
System.out.println("==targetTabPane.setOnDragExited");
event.consume();
});
targetTabPane.setOnDragEntered(event -> {
System.out.println("==targetTabPane.setOnDragEntered");
event.consume();
});
targetTabPane.setOnDragDone(event -> {
System.out.println("==targetTabPane.setOnDragDone");
event.consume();
});
}
public void onDragDetected(TabPane sourceTabPane) {
Tab selectedTab = sourceTabPane.getSelectionModel().getSelectedItem();
if (selectedTab != null) {
//将要拖放的tab的tabId放置到Dragboard中,供目标tabPane获取
Dragboard dragboard = sourceTabPane.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(selectedTab.getId());
dragboard.setContent(content);
System.out.println("sourceTabPane.setOnDragDetected==="+selectedTab.getId());
}
}
}