JAVA拖拽JscrollPanesun在java2中引入了一些新的方法来帮助实现拖拽功能,这些新的类在java.awt.dnd包中实现一个D&D操作一般包括三个步骤:首先实现一个拖拽源,这个拖拽源和相应的组件是关联起来的第二步实现一个拖拽目标,这个目标用来实现拖拽物的接收第三步实现一个数据传输对象,该对象封装拖动的数据__________________________________________|||||DragSourceComponent||DropTargetComponent||_____________________||____________________||||____________TransferableData_________________|Transferable接口实现出的对象能够保证DropTargetComponent读懂拖拽过来的对象中包含的信息如果是在同一个虚拟机中实现拖拽的话,DragSourceComponent会传递一个引用给DropTargetComponent但是如果在不同的JVM中或者是在JVM和本地系统之间传递数据的话我们就必须实现一个Transferable对象来传递数据Transferable中封装的内容存放到DataFlavors,用户可以通过访问DataFlavors来获取数据1。创建可拖拽对象一个对象那个如果想作为拖拽源的话,必须和五个对象建立联系,这五个对象分别是:*java.awt.dnd.DragSource获取DragSource的方法很简单,直接调用DragSource.getDefaultDragSource();就可以得到DragSource对象*java.awt.dnd.DragGestureRecognizerDragGestureRecognizer类中实现了一些与平台无关的方法,我们如果想在自己的组件上实现拖拽的话只要调用createDefaultDragGestureRecognizer()方法就可以了该方法接收三个参数,建立组件和拖拽动作之间的关系*java.awt.dnd.DragGestureListener当建立了组件和拖拽动作之间的联系后,如果用户执行了拖拽操作,组件将发送一个消息给DragGestureListener监听器DragGestureListener监听器接下来会发送一个startDrag()消息给拖拽源对象,告诉组件应该执行拖拽的初始化操作了拖拽源会产生一个DragSourceContext对象来监听动作的状态,这个监听过程是通过监听本地方法DragSourceContextPeer来实现的*java.awt.datatransfer.Transferable*java.awt.dnd.DragSourceListenerDragSourceListener接口负责当鼠标拖拽对象经过组件时的可视化处理,DragSourceListener接口的显示结果只是暂时改变组件的外观同时他提供一个feedback,当用户的拖拽操作完成之后会收到一个dragDropEnd的消息,我们可以在这个函数中执行相应的操作再来回顾一下拖拽源的建立过程首先、DragGestureRecognizer确认一个拖拽操作,同时告知DragGestureListener.其次、Assumingtheactionsand/orflavorsareOK,DragGestureListenerasksDragSourcetostartDrag().第三、DragSourcecreatesaDragSourceContextandaDragSourceContextPeer.TheDragSourceContextaddsitselfasaDragSourceListenertotheDragSourceContextPeer.第四、DragSourceContextPeerreceivesstatenotifications(componententered/exited/isover)fromthenativesystemanddelegatesthemtotheDragSourceContext.第五、TheDragSourceContextnotifiestheDragSourceListener,whichprovidesdragoverfeedback(iftheDropTargetListeneracceptstheaction).TypicalfeedbackincludesaskingtheDragSourceContexttochangethecursor.最后、Whenthedropiscomplete,theDragSourceListenerreceivesadragDropEndnotificationmessage2。创建droppableComponent创建一个droppableComponent必须和下面两个对象发生关联*java.awt.dnd.DropTargetDropTarget构造函数使DropTarget和DropTargetListenerobjects发生关联Droptarget对象提供setComponent和addDropTargetListener两个方法*java.awt.dnd.DropTargetListenerTheDropTargetListenerneedsanassociationwiththeComponentsothattheComponentcannotifytheDropTargetListenertodisplaydragundereffectsduringtheoperation.Thislistener,whichcanbeconvenientlycreatedasaninnerclass,transfersthedatawhenthedropoccurs.Warning:TheComponentitselfshouldn'tbethelistener,sincethisimpliesitsavailabilityforuseassomeotherComponent'slistener.代码如下:publicclassDragAndDropextendsJFrame{privatestaticfinallongserialVersionUID=1L;JScrollPanejScrollPane1=newJScrollPane();JTextFieldjtf=newJTextField();publicDragAndDrop(){getContentPane().setLayout(newBorderLayout());setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jtf.setBackground(Color.yellow);jtf.setSize(100,80);JPanelpanel1=newJPanel(newBorderLayout());panel1.add(jtf,BorderLayout.CENTER);JTreejtr=newJTree();jScrollPane1.getViewport().add(jtr);add(panel1,BorderLayout.SOUTH);add(jScrollPane1,BorderLayout.CENTER);DragSourcedragSource=DragSource.getDefaultDragSource();//创建拖拽源dragSource.createDefaultDragGestureRecognizer(jtr,DnDConstants.ACTION_COPY_OR_MOVE,newMyDragGestureListener());//建立拖拽源和事件的联系newDropTarget(jtf,newMyTargetListener());}publicstaticvoidmain(String[]args){DragAndDropdad=newDragAndDrop();dad.setTitle(拖拽演示);dad.setSize(400,300);dad.setVisible(true);}}classMyDragGestureListenerimplementsDragGestureListener{publicvoiddragGestureRecognized(DragGestureEventdge){//将数据存储到Transferable中,然后通知组件开始调用startDrag()初始化JTreetree=(JTree)dge.getComponent();TreePathpath=tree.getSelectionPath();if(path!=null){DefaultMutableTreeNodeselection=(DefaultMutableTreeNode)path.getLastPathComponent();MyTransferabledragAndDropTransferable=newMyTransferable(selection);dge.startDrag(DragSource.DefaultCopyDrop,dragAndDropTransferable,newMySourceListener());}}}classMyTransferableimplementsTransferable{privateDefaultMutableTreeNodetreeNode;MyTransferable(DefaultMutableTreeNodetreeNode){this.treeNode=treeNode;}staticDataFlavorflavors[]={DataFlavor.stringFlavor};publicDataFlavor[]getTransferDataFlavors(){returnflavors;}publicbooleanisDataFlavorSupported(DataFlavorflavor){//if(treeNode.getChildCount()==0){//returntrue;//}returntrue;}publicObjectgetTransferData(DataFlavorflavor)throwsUnsupportedFlavorException,IOException{returntreeNode;}}classMySourceListenerimplementsDragSourceListener{publicvoiddragDropEnd(DragSourceDropEventdragSourceDropEvent){if(dragSourceDropEvent.getDropSuccess()){//拖拽动作结束的时候打印出移动节点的字符串intdropAction=dragSourceDropEvent.getDropAction();if(dropAction==DnDConstants.ACTION_MOVE){System.out.println(MOVE:removenode);}}}publicvoiddragEnter(DragSourceDragEventdragSourceDragEvent){DragSourceContextcontext=dragSourceDragEvent.getDragSourceContext();intdropAction=dragSourceDragEvent.getDropAction();if((dropAction&DnDConstants.ACTION_COPY)!=0)