/Users/lyon/j4p/src/gui/tree/PanelDropTarget.java

1    package gui.tree; 
2     
3    import javax.swing.*; 
4    import java.awt.*; 
5    import java.awt.datatransfer.DataFlavor; 
6    import java.awt.datatransfer.Transferable; 
7    import java.awt.datatransfer.UnsupportedFlavorException; 
8    import java.awt.dnd.*; 
9    import java.awt.event.WindowAdapter; 
10   import java.awt.event.WindowEvent; 
11   import java.io.IOException; 
12    
13   public class PanelDropTarget implements DropTargetListener { 
14       public PanelDropTarget(JPanel pane) { 
15           this.pane = pane; 
16    
17           // Create the DropTarget and register 
18           // it with the JPanel. 
19           dropTarget = new DropTarget(pane, 
20                   DnDConstants.ACTION_COPY_OR_MOVE, 
21                   this, true, null); 
22       } 
23    
24       // Implementation of the DropTargetListener interface 
25       public void dragEnter(DropTargetDragEvent dtde) { 
26           DnDUtils.debugPrintln("dragEnter, drop action = " 
27                   + DnDUtils.showActions(dtde.getDropAction())); 
28    
29           // Get the type of object being transferred and determine 
30           // whether it is appropriate. 
31           checkTransferType(dtde); 
32    
33           // Accept or reject the drag. 
34           acceptOrRejectDrag(dtde); 
35       } 
36    
37       public void dragExit(DropTargetEvent dte) { 
38           DnDUtils.debugPrintln("DropTarget dragExit"); 
39       } 
40    
41       public void dragOver(DropTargetDragEvent dtde) { 
42           DnDUtils.debugPrintln("DropTarget dragOver, drop action = " 
43                   + DnDUtils.showActions(dtde.getDropAction())); 
44    
45           // Accept or reject the drag 
46           acceptOrRejectDrag(dtde); 
47       } 
48    
49       public void dropActionChanged(DropTargetDragEvent dtde) { 
50           DnDUtils.debugPrintln("DropTarget dropActionChanged, drop action = " 
51                   + DnDUtils.showActions(dtde.getDropAction())); 
52    
53           // Accept or reject the drag 
54           acceptOrRejectDrag(dtde); 
55       } 
56    
57       public void drop(DropTargetDropEvent dtde) { 
58           DnDUtils.debugPrintln("DropTarget drop, drop action = " 
59                   + DnDUtils.showActions(dtde.getDropAction())); 
60    
61           // Check the drop action 
62           if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0) { 
63               // Accept the drop and get the transfer data 
64               dtde.acceptDrop(dtde.getDropAction()); 
65               Transferable transferable = dtde.getTransferable(); 
66    
67               try { 
68                   boolean result = dropComponent(transferable); 
69    
70                   dtde.dropComplete(result); 
71                   DnDUtils.debugPrintln("Drop completed, success: " + result); 
72               } catch (Exception e) { 
73                   DnDUtils.debugPrintln("Exception while handling drop " + e); 
74                   dtde.dropComplete(false); 
75               } 
76           } else { 
77               DnDUtils.debugPrintln("Drop target rejected drop"); 
78               dtde.rejectDrop(); 
79           } 
80       } 
81    
82       // Internal methods start here 
83    
84       protected boolean acceptOrRejectDrag(DropTargetDragEvent dtde) { 
85           int dropAction = dtde.getDropAction(); 
86           int sourceActions = dtde.getSourceActions(); 
87           boolean acceptedDrag = false; 
88    
89           DnDUtils.debugPrintln("\tSource actions are " + 
90                   DnDUtils.showActions(sourceActions) + 
91                   ", drop action is " + 
92                   DnDUtils.showActions(dropAction)); 
93    
94           // Reject if the object being transferred 
95           // or the operations available are not acceptable. 
96           if (!acceptableType || 
97                   (sourceActions & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { 
98               DnDUtils.debugPrintln("Drop target rejecting drag"); 
99               dtde.rejectDrag(); 
100          } else if ((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { 
101              // Not offering copy or move - suggest a copy 
102              DnDUtils.debugPrintln("Drop target offering COPY"); 
103              dtde.acceptDrag(DnDConstants.ACTION_COPY); 
104              acceptedDrag = true; 
105          } else { 
106              // Offering an acceptable operation: accept 
107              DnDUtils.debugPrintln("Drop target accepting drag"); 
108              dtde.acceptDrag(dropAction); 
109              acceptedDrag = true; 
110          } 
111   
112          return acceptedDrag; 
113      } 
114   
115      protected void checkTransferType(DropTargetDragEvent dtde) { 
116          // Only accept a flavor that returns a Component 
117          acceptableType = false; 
118          DataFlavor[] fl = dtde.getCurrentDataFlavors(); 
119          for (int i = 0; i < fl.length; i++) { 
120              Class dataClass = fl[i].getRepresentationClass(); 
121   
122              if (Component.class.isAssignableFrom(dataClass)) { 
123                  // This flavor returns a Component - accept it. 
124                  targetFlavor = fl[i]; 
125                  acceptableType = true; 
126                  break; 
127              } 
128          } 
129   
130          DnDUtils.debugPrintln("File type acceptable - " + acceptableType); 
131      } 
132   
133      protected boolean dropComponent(Transferable transferable) 
134              throws IOException, UnsupportedFlavorException { 
135          Object o = transferable.getTransferData(targetFlavor); 
136          if (o instanceof Component) { 
137              DnDUtils.debugPrintln("Dragged component class is " + o.getClass().getName()); 
138              pane.add((Component) o); 
139              pane.validate(); 
140              return true; 
141          } 
142          return false; 
143      } 
144   
145      public static void main(String[] args) { 
146          final JFrame f = new JFrame("Component drop target example"); 
147   
148          JPanel pane = new JPanel(); 
149   
150          // Add a drop target to the JPanel 
151          PanelDropTarget target = new PanelDropTarget(pane); 
152   
153          f.addWindowListener(new WindowAdapter() { 
154              public void windowClosing(WindowEvent evt) { 
155                  System.exit(0); 
156              } 
157          }); 
158   
159          f.getContentPane().add(new JScrollPane(pane), BorderLayout.CENTER); 
160          f.setSize(500, 400); 
161          f.setVisible(true); 
162      } 
163   
164      protected JPanel pane; 
165      protected DropTarget dropTarget; 
166      protected boolean acceptableType;   // Indicates whether data is acceptable 
167      protected DataFlavor targetFlavor;  // Flavor to use for transfer 
168  } 
169   
170