[b]一、介绍[/b]
为应用程序添加拖拽效果,或许更加能发挥用户操作主动性和灵活性了。记事本,for example,在选择点击open按钮打开文件与直接将文件拖拽到一个打开的记事本程序相比,或许大家会选择后者(这里只是拿记事本举例,就不必提为什么不双击文件之类云云了),一个是用户主动性有很大的改善,而不必按照程序设计人员提供的点击某按钮或某快捷键等来唤起操作相应了,同时从某种角度说,也提升了用户体验。另外,拖拽为GUI中的不同实体间显式传送数据提供了便捷的方式。所以在程序中恰当的应用拖拽效果,对改善软件友好性有一定帮助的。
这里,介绍一下java dnd拖拽的实现,欢迎大家拍砖。
关于java dnd 拖拽实现的原理介绍,请参考该博文[url=http://netbaixc-gmail-com.iteye.com/blog/281356]Java dnd拖拽实现分析纪要[/url],这里就不再讨论了。
简单来说,拖拽效果由一下主要几个过程组成:
·拖拽进入
·拖拽经过
·拖拽释放
·拖拽离开等
笔者学习习惯是先看效果,再深入了解其本质内容,所以在这里还是先演示如何为程序添加拖拽效果。
[b]二、准备工作[/b]
新建一个java工程,设计一个窗口,窗口使用BordLayout布局,内含一个JTextArea(textArea),为后面拖拽文件到该窗口后显式文件内容用。效果如下图:
[img]http://shansun123.iteye.com/upload/picture/pic/33389/f9c29c16-c4ba-3dc0-8046-edde2b7e1da5.jpg[/img]
PS:为了后面操作简单性,我们将textArea的访问声明设置为public static。
[b]三、编程实现拖拽效果[/b]
第一步:新建一个类实现DropTargetListener接口。如下:
public class DndTargetListener implements DropTargetListener {
@Override
public void dragEnter(DropTargetDragEvent arg0) {
}
@Override
public void dragExit(DropTargetEvent arg0) {
}
@Override
public void dragOver(DropTargetDragEvent arg0) {
}
@Override
public void drop(DropTargetDropEvent arg0) {
}
@Override
public void dropActionChanged(DropTargetDragEvent arg0) {
}
}
观察代码,各方法的功能都可以从字面意思上理解。当然这里拖拽效果演示的是释放文件后读取文件内容,所以这里实现的是DropTargetListener接口,如果你还想对被拖拽对象进行处理或管理,则还可以实现DragSourceListener接口,还有其他一些接口提供不同的功能,如DragGestureListener等。
第二步:实现相应的方法。
我们当然不想什么文件都可以拖到该窗口内,如exe文件、com文件等,所以我们要过滤掉一些文件。这个需求我们可以在dragEnter方法中进行处理。在该方法里添加代码片段:
if (!arg0.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
&& !arg0.isDataFlavorSupported(DataFlavor.stringFlavor)) {
arg0.rejectDrag();
}
这里提一下,DataFlavor.javaFileListFlavor是设定要将文件列表传入 Java(即基础平台)或从中传出。其他的还有像imageFlavor、stringFlavor、plainTextFlavor等。想了解更多的可以参考Java API。
这里我们对“拖拽离开”动作不做处理。“拖拽经过”动作和“拖拽进入”操作相同,也可不做处理。
第二步:处理拖拽释放动作,即实现drop方法。先粘代码,具体代码如下:
public void drop(DropTargetDropEvent arg0) {
arg0.acceptDrop(DnDConstants.ACTION_REFERENCE);
if (arg0.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
try {
Transferable tf = arg0.getTransferable();
List<File> list = (List<File>) tf
.getTransferData(DataFlavor.javaFileListFlavor);
for (File f : list) {
if (f.exists() && f.isFile()) {
MainFrm.textArea.append(f.getAbsolutePath() + "\n");
MainFrm.textArea.append("======================\n");
br = new BufferedReader(new FileReader(f));
while ((line = br.readLine()) != null)
MainFrm.textArea.append(line + "\n");
br.close();
} else if (f.exists() && f.isDirectory()) {
// 这里不对拖拽文件夹做操作
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里实现的功能是当同时拖拽多个文件到文本框时,则显示各文件绝对路径和内容。代码就不详细分析了,主要说的是,前面设定的DataFlavor为javaFileListFlavor,这里获得的是个文件列表(list),所以我们这里使用一个List来接收。
第三步:为textArea添加对拖拽效果的支持。代码实现如下:
dnd = new DndTargetListener();
textArea.setDropTarget(new DropTarget(this, DnDConstants.ACTION_REFERENCE,
dnd, true));
这样一个简单的拖拽效果演示程序就完成了,最后我们来跑起来看看吧。
[img]http://shansun123.iteye.com/upload/picture/pic/33391/ba153aa2-49ef-3250-adde-409be9a3d355.jpg[/img]