JList的拖拽排序实现

最近实现了一个封装后的支持拖拽排序的JList,以下为源代码

重点关注三点:

1、定义拖拽源

2、定义放置目标

3、定义数据传输格式

其中拖起源定义(DragSource)见37-38行,分别定义支持拖拽的组件,拖拽类型以及拖拽监听器定义放置目标(DropTarget)见39行,分别定义接受拖拽的组件以及对应drop监听

数据传输格式(Transferable)见47行,定义拖拽过程中数据传输类型,此处为自定义的数据传输对象ReportObjTransferable,具体参见下方代码

  1 public class ReorderableList extends JList
  2     implements
  3       DragSourceListener,
  4       DropTargetListener,
  5       DragGestureListener {
  6 
  7   private static final long serialVersionUID = -961840807598972987L;
  8   /**
  9    * 拖源
 10    */
 11   DragSource dragSource;
 12   /**
 13    * 放置目标
 14    */
 15   DropTarget dropTarget;
 16   /**
 17    * 放置对象
 18    */
 19   Object dropTargetCell;
 20   /**
 21    * 被拖对象index
 22    */
 23   int draggedIndex = -1;
 24   
 25 
 26   /**
 27    * 获取放置对象
 28    * 
 29    * @return
 30    */
 31   public Object getDropTargetCell() {
 32     return dropTargetCell;
 33   }
 34 
 35   public ReportReorderableList() {
 36     super();
 37     dragSource =  DragSource.getDefaultDragSource();
 38     dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
 39     dropTarget = new DropTarget(this, this);
 40   }
 41 
 42   public void dragGestureRecognized(DragGestureEvent dge) {
 43     Point clickPoint = dge.getDragOrigin();
 44     int index = locationToIndex(clickPoint);
 45     if (index == -1) return;
 46     Object target = getModel().getElementAt(index);
 47     Transferable trans = new ReportObjTransferable(target);
 48     draggedIndex = index;
 49     dragSource.startDrag(dge, Cursor.getDefaultCursor(), trans, this);
 50   }
 51 
 52   public void dragEnter(DropTargetDragEvent dtde) {
 53     if (dtde.getSource() != dropTarget)
 54       dtde.rejectDrag();
 55     else {
 56       dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
 57     }
 58   }
 59 
 60   public void dragOver(DropTargetDragEvent dtde) {
 61 
 62     if (dtde.getSource() != dropTarget) dtde.rejectDrag();
 63     // 拿到拖放的目标位置
 64     Point dragPoint = dtde.getLocation();
 65     int index = locationToIndex(dragPoint);
 66     if (index == -1)
 67       dropTargetCell = null;
 68     else
 69       dropTargetCell = getModel().getElementAt(index);
 70     repaint();
 71   }
 72 
 73   public void dropActionChanged(DropTargetDragEvent dtde) {}
 74 
 75   public void dragExit(DropTargetEvent dte) {}
 76 
 77   public void drop(DropTargetDropEvent dtde) {
 78     if (dtde.getSource() != dropTarget) {
 79       dtde.rejectDrop();
 80       return;
 81     }
 82     Point dropPoint = dtde.getLocation();
 83     int index = locationToIndex(dropPoint);
 84     boolean dropped = false;
 85     try {
 86      DefaultListModel mod = (DefaultListModel) getModel();
 87       Object dragged = dtde.getTransferable().getTransferData(ReportDataFlavor.localObjectFlavor);
 88       // 判断拖拽的对象是否在JList内以及是否已含有当前拖拽对象,不满足条件则不允许放置
 89       if ((index == -1 && mod.size()>0) || (index == draggedIndex && index!=-1) || (draggedIndex == -1 && mod.contains(dragged))) {
 90         dtde.rejectDrop();
 91         return;
 92       }
 93       dtde.acceptDrop(DnDConstants.ACTION_MOVE);
 94       // 不是从当前面板拖拽的对象,则添加
 95       if (draggedIndex == -1) {
 96         mod.add(mod.getSize(), dragged);
 97       } else {
 98         // 从当前面板拖拽的对象,则进行顺序调整
 99         boolean sourceBeforeTarget = (draggedIndex < index);
100         mod.remove(draggedIndex);
101         mod.add((sourceBeforeTarget ? index - 1 : index), dragged);
102       }
103       dropped = true;
104     } catch (Exception e) {
105       e.printStackTrace();
106     }
107     dtde.dropComplete(dropped);
108   }
109   
110   public void add(Object obj){
111     DefaultListModel mod = (DefaultListModel) getModel();
112     mod.addElement(obj);
113   }
114 
115   public void dragEnter(DragSourceDragEvent dsde) {}
116 
117   public void dragOver(DragSourceDragEvent dsde) {}
118 
119   public void dropActionChanged(DragSourceDragEvent dsde) {}
120 
121   public void dragExit(DragSourceEvent dse) {}
122 
123   public void dragDropEnd(DragSourceDropEvent dsde) {
124     dropTargetCell = null;
125     draggedIndex = -1;
126     repaint();
127   }
128   
129 
130 }

 

 

 1 public class ReportObjTransferable implements Transferable {
 2   Object object;
 3   static DataFlavor[] supportedFlavors = {ReportDataFlavor.localObjectFlavor};
 4 
 5   public ReportObjTransferable(Object obj) {
 6     this.object = obj;
 7   }
 8 
 9   public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException {
10     if (isDataFlavorSupported(df))
11       return object;
12     else
13       throw new UnsupportedFlavorException(df);
14   }
15 
16   public boolean isDataFlavorSupported(DataFlavor df) {
17     return (df.equals(ReportDataFlavor.localObjectFlavor));
18   }
19 
20   public DataFlavor[] getTransferDataFlavors() {
21     return supportedFlavors;
22   }
23 
24 }

 

 1 public class ReportDataFlavor {
 2   /**
 3    * swing控件
 4    */
 5   public static DataFlavor componentFlavor = createConstant(JComponent.class,
 6       JComponent.class.getName());11   /**
12    * 本地对象类型
13    */
14   public static DataFlavor localObjectFlavor = createConstant(DataFlavor.javaJVMLocalObjectMimeType);
15 
16 
17   /**
18    * 数据类型构造
19    * 
20    * @param rc
21    * @param prn
22    * @return
23    */
24   static private DataFlavor createConstant(Class rc, String prn) {
25     try {
26       return new DataFlavor(rc, prn);
27     } catch (Exception e) {
28       e.printStackTrace();
29       return null;
30     }
31   }
32 
33   static private DataFlavor createConstant(String mimeType) {
34     try {
35       return new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType);
36     } catch (ClassNotFoundException cnfe) {
37       cnfe.printStackTrace();
38       return null;
39     }
40   }
41 }

 

posted on 2013-04-16 20:00  guosean  阅读(851)  评论(0编辑  收藏  举报

导航