KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > explorer > view > ListViewDropSupport


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.openide.explorer.view;
20
21 import org.openide.nodes.Node;
22 import org.openide.util.RequestProcessor;
23 import org.openide.util.datatransfer.PasteType;
24
25 import java.awt.datatransfer.*;
26 import java.awt.dnd.*;
27
28 import javax.swing.JList JavaDoc;
29 import javax.swing.SwingUtilities JavaDoc;
30
31
32 /**
33 *
34 * @author Dafe Simonek
35 */

36 final class ListViewDropSupport implements DropTargetListener, Runnable JavaDoc {
37     // Attributes
38

39     /** true if support is active, false otherwise */
40     boolean active = false;
41     boolean dropTargetPopupAllowed;
42
43     /** Drop target asociated with the tree */
44     DropTarget dropTarget;
45
46     /** The index of last item the cursor hotspot was above */
47     int lastIndex = -1;
48
49     // Associations
50

51     /** View manager. */
52     protected ListView view;
53
54     /** The component we are supporting with drop support */
55     protected JList JavaDoc list;
56
57     // Operations
58
public ListViewDropSupport(ListView view, JList JavaDoc list) {
59         this(view, list, true);
60     }
61
62     /** Creates new TreeViewDropSupport */
63     public ListViewDropSupport(ListView view, JList JavaDoc list, boolean dropTargetPopupAllowed) {
64         this.view = view;
65         this.list = list;
66         this.dropTargetPopupAllowed = dropTargetPopupAllowed;
67     }
68
69     public void setDropTargetPopupAllowed(boolean value) {
70         dropTargetPopupAllowed = value;
71     }
72
73     public boolean isDropTargetPopupAllowed() {
74         return dropTargetPopupAllowed;
75     }
76
77     /** User is starting to drag over us */
78     public void dragEnter(DropTargetDragEvent dtde) {
79         ExplorerDnDManager.getDefault().setMaybeExternalDragAndDrop( true );
80         int dropAction = ExplorerDnDManager.getDefault().getAdjustedDropAction(
81                 dtde.getDropAction(), view.getAllowedDropActions()
82             );
83
84         lastIndex = indexWithCheck(dtde);
85
86         if (lastIndex < 0) {
87             dtde.rejectDrag();
88         } else {
89             dtde.acceptDrag(dropAction);
90             NodeRenderer.dragEnter(list.getModel().getElementAt(lastIndex));
91             list.repaint(list.getCellBounds(lastIndex, lastIndex));
92         }
93     }
94
95     /** User drags over us */
96     public void dragOver(DropTargetDragEvent dtde) {
97         ExplorerDnDManager.getDefault().setMaybeExternalDragAndDrop( true );
98         int dropAction = ExplorerDnDManager.getDefault().getAdjustedDropAction(
99                 dtde.getDropAction(), view.getAllowedDropActions()
100             );
101
102         int index = indexWithCheck(dtde);
103
104         if (index < 0) {
105             dtde.rejectDrag();
106
107             if (lastIndex >= 0) {
108                 NodeRenderer.dragExit();
109                 list.repaint(list.getCellBounds(lastIndex, lastIndex));
110                 lastIndex = -1;
111             }
112         } else {
113             dtde.acceptDrag(dropAction);
114
115             if (lastIndex != index) {
116                 if (lastIndex < 0) {
117                     lastIndex = index;
118                 }
119
120                 NodeRenderer.dragExit();
121                 NodeRenderer.dragEnter(list.getModel().getElementAt(index));
122                 list.repaint(list.getCellBounds(lastIndex, index));
123                 lastIndex = index;
124             }
125         }
126     }
127
128     public void dropActionChanged(DropTargetDragEvent dtde) {
129         // PENDING...?
130
}
131
132     /** User exits the dragging */
133     public void dragExit(DropTargetEvent dte) {
134         ExplorerDnDManager.getDefault().setMaybeExternalDragAndDrop( false );
135         if (lastIndex >= 0) {
136             NodeRenderer.dragExit();
137             list.repaint(list.getCellBounds(lastIndex, lastIndex));
138         }
139     }
140
141     /** Performs the drop action, if we are dropping on
142     * right node and target node agrees.
143     */

144     public void drop(DropTargetDropEvent dtde) {
145         // obtain the node we have cursor on
146
int index = list.locationToIndex(dtde.getLocation());
147         Object JavaDoc obj = list.getModel().getElementAt(index);
148         Node dropNode = null;
149
150         if (obj instanceof VisualizerNode) {
151             dropNode = ((VisualizerNode) obj).node;
152         }
153
154         int dropAction = ExplorerDnDManager.getDefault().getAdjustedDropAction(
155                 dtde.getDropAction(), view.getAllowedDropActions()
156             );
157
158         ExplorerDnDManager.getDefault().setMaybeExternalDragAndDrop( false );
159
160         // return if conditions are not satisfied
161
if ((index < 0) || !canDrop(dropNode, dropAction, dtde.getTransferable(), index)) {
162             dtde.rejectDrop();
163
164             return;
165         }
166
167         // get paste types for given transferred transferable
168
Transferable t = ExplorerDnDManager.getDefault().getDraggedTransferable((DnDConstants.ACTION_MOVE & dropAction) != 0);
169         if( null == t )
170             t = dtde.getTransferable();
171         PasteType pt = DragDropUtilities.getDropType( dropNode, t, dropAction, index );
172
173         if (pt == null) {
174             dtde.dropComplete(false);
175
176             // something is wrong, notify user
177
// ugly hack, but if we don't wait, deadlock will come
178
// (sun's issue....)
179
RequestProcessor.getDefault().post(this, 500);
180
181             return;
182         }
183
184         // finally perform the drop
185
dtde.acceptDrop(dropAction);
186
187         if (dropAction == DnDConstants.ACTION_LINK) {
188             // show popup menu to the user
189
// PENDING
190
} else {
191             DragDropUtilities.performPaste(pt, null);
192         }
193     }
194
195     /** Can node recieve given drop action? */
196
197     // XXX canditate for more general support
198
private boolean canDrop(Node n, int dropAction, Transferable dndEventTransferable, int dropIndex) {
199         if (n == null) {
200             return false;
201         }
202
203         if (ExplorerDnDManager.getDefault().getNodeAllowedActions() == DnDConstants.ACTION_NONE) {
204             return false;
205         }
206
207         // test if a parent of the dragged nodes isn't the node over
208
// only for MOVE action
209
if ((DnDConstants.ACTION_MOVE & dropAction) != 0) {
210             Node[] nodes = ExplorerDnDManager.getDefault().getDraggedNodes();
211
212             if( null != nodes ) {
213                 for (int i = 0; i < nodes.length; i++) {
214                     if (n.equals(nodes[i].getParentNode())) {
215                         return false;
216                     }
217                 }
218             }
219         }
220
221         Transferable trans = ExplorerDnDManager.getDefault().getDraggedTransferable(
222                 (DnDConstants.ACTION_MOVE & dropAction) != 0
223             );
224
225         if (trans == null) {
226             trans = dndEventTransferable;
227             if( trans == null ) {
228                 return false;
229             }
230         }
231
232         // get paste types for given transferred transferable
233
PasteType pt = DragDropUtilities.getDropType(n, trans, dropAction, dropIndex);
234
235         return (pt != null);
236     }
237
238     /** Activates or deactivates Drag support on asociated JTree
239     * component
240     * @param active true if the support should be active, false
241     * otherwise
242     */

243     public void activate(boolean active) {
244         if (this.active == active) {
245             return;
246         }
247
248         this.active = active;
249         getDropTarget().setActive(active);
250     }
251
252     /** Implementation of the runnable interface.
253     * Notifies user in AWT thread. */

254     public void run() {
255         if (!SwingUtilities.isEventDispatchThread()) {
256             SwingUtilities.invokeLater(this);
257
258             return;
259         }
260
261         DragDropUtilities.dropNotSuccesfull();
262     }
263
264     /** @return The tree path to the node the cursor is above now or
265     * null if no such node currently exists or if conditions were not
266     * satisfied to continue with DnD operation.
267     */

268     int indexWithCheck(DropTargetDragEvent dtde) {
269         int dropAction = ExplorerDnDManager.getDefault().getAdjustedDropAction(
270                 dtde.getDropAction(), view.getAllowedDropActions()
271             );
272
273         // check actions
274
if ((dropAction & view.getAllowedDropActions()) == 0) {
275             return -1;
276         }
277
278         // check location
279
int index = list.locationToIndex(dtde.getLocation());
280         if (index == -1) return -1;
281         Object JavaDoc obj = list.getModel().getElementAt(index);
282
283         if (obj instanceof VisualizerNode) {
284             obj = ((VisualizerNode) obj).node;
285         }
286
287         if (index < 0) {
288             return -1;
289         }
290
291         if (!(obj instanceof Node)) {
292             return -1;
293         }
294
295         /* JST: Is necessary? Cannot be replaced by the use of special
296         * transferable?
297
298         // accept only node data flavors or multi flavor
299         if (!dtde.isDataFlavorSupported(NodeTransfer.nodeCutFlavor) &&
300             !dtde.isDataFlavorSupported(NodeTransfer.nodeCopyFlavor) &&
301             !dtde.isDataFlavorSupported(ExTransferable.multiFlavor))
302           return -1;
303         */

304
305         // succeeded
306
return index;
307     }
308
309     /** Safe accessor to the drop target which is asociated
310     * with the tree */

311     DropTarget getDropTarget() {
312         if (dropTarget == null) {
313             dropTarget = new DropTarget(list, view.getAllowedDropActions(), this, false);
314         }
315
316         return dropTarget;
317     }
318 }
319
Popular Tags