示例内容:
从Drag Me的标签拖动到 Drop On Me标签上。
从本地,拖动一个图片 到 drag a image to this的标签下面,可以显示你拖动的图片。
从本地,拖动一个文本文件 到 drag a txt to this的标签下面,可以显示你拖动的文本的内容(因为编码问题可能乱码,可以使用UTF-8等编码的文本)。
截图如下:
在JavaFX中关于拖放操作,可以设置这么几种事件监听器。
setOnDragDetected(new EventHandler<MouseEvent>());
当你从一个Node上进行拖动的时候,会检测到拖动操作,将会执行这个EventHandler。
setOnDragEntered(new EventHandler<DragEvent>());
当你拖动到目标控件的时候,会执行这个事件回调。
setOnDragExited(new EventHandler<DragEvent>());
当你拖动移出目标控件的时候,执行这个操作。
setOnDragOver(new EventHandler<DragEvent>());
当你拖动到目标上方的时候,会不停的执行。
setOnDragDropped(new EventHandler<DragEvent>());
当你拖动到目标并松开鼠标的时候,执行这个DragDropped事件。
setOnDragDone(new EventHandler<DragEvent>());
当你拖动并松手的时候,执行Drag完成操作。
这里要注意的是,首先执行拖动,拖动到目标控件的时候,会首先执行DragEnter,这个只执行一遍。然后当你停留在目标控件上方的时候,会不停的指定DragOver操作。
下面我们来看看示例中的代码:
m_drag.setOnDragDetected(new EventHandler() {
@Override
public void handle(MouseEvent event) {
Dragboard dragboard = m_drag.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(m_drag.getText());
dragboard.setContent(content);
}
});
m_drop.setOnDragEntered(new EventHandler() {
@Override
public void handle(DragEvent event) {
m_drop.setTextFill(Color.RED);
}
});
m_drop.setOnDragExited(new EventHandler() {
@Override
public void handle(DragEvent event) {
m_drop.setTextFill(Color.BLACK);
}
});
m_drop.setOnDragOver(new EventHandler() {
@Override
public void handle(DragEvent event) {
if (event.getGestureSource() != m_drop && event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
}
});
m_drop.setOnDragDropped(new EventHandler() {
@Override
public void handle(DragEvent event) {
Dragboard dragboard = event.getDragboard();
m_drop.setText(dragboard.getString());
}
});
m_drag.setOnDragDone(new EventHandler() {
@Override
public void handle(DragEvent event) {
m_drag.setText("");
}
});
其中m_drag是Drag Me标签Label。m_drop是Drop on Me标签Label。
我们在检测到拖动m_drag标签的时候,使用了一个Dragboard,俗称"拖板"(...), 当然不能这样称呼,但是很明显,它就类似于ClipBoard剪切板。我们将拖动要传送的数据使用ClipboardContent设置到Dragboard上。
其他的就是比较简单的,当拖动到m_drop上面的时候,改变m_drop的颜色。
在DragOver的时候 通过event.acceptTransferModes(TransferMode.ANY);来设置接收数据的类型。
在Drag松开的时候,通过获取Dragboard的数据,来设置到标签上。
上面是JavaFX中 控件与控件之间拖动数据的示例。当然很多处理不得当,只是为了演示所有的拖动方法,所以才将每个事件都使用到。
下面来看看拖动文件的:
m_imageView.setOnDragOver(new EventHandler() {
@Override
public void handle(DragEvent event) {
if (event.getGestureSource() != m_imageView) {
event.acceptTransferModes(TransferMode.ANY);
}
}
});
m_imageView.setOnDragDropped(new EventHandler() {
@Override
public void handle(DragEvent event) {
Dragboard dragboard = event.getDragboard();
List files = dragboard.getFiles();
if(files.size() > 0){
try {
m_imageView.setImage(new Image(new FileInputStream(files.get(0))));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
});
这里只有一个DragOver和DragDropped。
松手之后,同样通过 Dragboard获取拖动的文件列表,我们这里将拖动到的第一个文件当作数据流创建图片并设置到imageView中。
这里的操作比较简单,其实可以做更为复杂的判断。
文本也是相同的:
m_textArea.setOnDragOver(new EventHandler() {
@Override
public void handle(DragEvent event) {
if (event.getGestureSource() != m_imageView) {
event.acceptTransferModes(TransferMode.ANY);
}
}
});
m_textArea.setOnDragDropped(new EventHandler() {
@Override
public void handle(DragEvent event) {
Dragboard dragboard = event.getDragboard();
List files = dragboard.getFiles();
if(files.size() > 0){
m_textArea.setText(FileTools.readFile(files.get(0)));
}
}
});
文章评论