KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > spi > palette > DragAndDropHandler


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
20
21 package org.netbeans.spi.palette;
22 import java.awt.datatransfer.DataFlavor JavaDoc;
23 import java.awt.datatransfer.Transferable JavaDoc;
24 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
25 import java.io.IOException JavaDoc;
26 import org.netbeans.modules.palette.DefaultModel;
27 import org.openide.ErrorManager;
28 import org.openide.nodes.Index;
29 import org.openide.nodes.Node;
30 import org.openide.util.Lookup;
31 import org.openide.util.datatransfer.ExTransferable;
32 import org.openide.util.datatransfer.PasteType;
33 /**
34  * <p>An abstract class implemented by palette clients to implement drag and drop
35  * of new items into the palette window and to customize the default Transferable
36  * instance of items being dragged from the palette window to editor area.</p>
37  *
38  * <p>Client's can support multiple DataFlavors that may help to enable/disable the drop
39  * when dragging an item over different editor area parts that allow only certain
40  * item types to be dropped into them.</p>
41  *
42  * @author S. Aubrecht
43  */

44 public abstract class DragAndDropHandler {
45
46     private static DragAndDropHandler defaultHandler;
47     
48     static DragAndDropHandler getDefault() {
49         if( null == defaultHandler )
50             defaultHandler = new DefaultDragAndDropHandler();
51         return defaultHandler;
52     }
53     
54     /**
55      * Add your own custom DataFlavor as need to suppor drag-over a different
56      * parts of editor area.
57      *
58      * @param t Item's default Transferable.
59      * @param item Palette item's Lookup.
60      *
61      */

62     public abstract void customize( ExTransferable t, Lookup item );
63     
64     /**
65      * @param targetCategory Lookup of the category under the drop cursor.
66      * @param flavors Supported DataFlavors.
67      * @param dndAction Drop action type.
68      *
69      * @return True if the given category can accept the item being dragged.
70      */

71     public boolean canDrop( Lookup targetCategory, DataFlavor JavaDoc[] flavors, int dndAction ) {
72         for( int i=0; i<flavors.length; i++ ) {
73             if( PaletteController.ITEM_DATA_FLAVOR.equals( flavors[i] ) ) {
74                 return true;
75             }
76         }
77         return false;
78     }
79     
80     /**
81      * Perform the drop operation and add the dragged item into the given category.
82      *
83      * @param targetCategory Lookup of the category that accepts the drop.
84      * @param item Transferable holding the item being dragged.
85      * @param dndAction Drag'n'drop action type.
86      * @param dropIndex Zero-based position where the dragged item should be dropped.
87      *
88      * @return True if the drop has been successful, false otherwise.
89      */

90     public boolean doDrop( Lookup targetCategory, Transferable JavaDoc item, int dndAction, int dropIndex ) {
91         Node categoryNode = (Node)targetCategory.lookup( Node.class );
92         try {
93             //first check if we're reordering items within the same category
94
if( item.isDataFlavorSupported( PaletteController.ITEM_DATA_FLAVOR ) ) {
95                 Lookup itemLookup = (Lookup)item.getTransferData( PaletteController.ITEM_DATA_FLAVOR );
96                 if( null != itemLookup ) {
97                     Node itemNode = (Node)itemLookup.lookup( Node.class );
98                     if( null != itemNode ) {
99                         Index order = (Index)categoryNode.getCookie( Index.class );
100                         if( null != order && order.indexOf( itemNode ) >= 0 ) {
101                             //the drop item comes from the targetCategory so let's
102
//just change the order of items
103
return moveItem( targetCategory, itemLookup, dropIndex );
104                         }
105                     }
106                 }
107             }
108             PasteType paste = categoryNode.getDropType( item, dndAction, dropIndex );
109             if( null != paste ) {
110                 Node[] itemsBefore = categoryNode.getChildren().getNodes( DefaultModel.canBlock() );
111                 paste.paste();
112                 Node[] itemsAfter = categoryNode.getChildren().getNodes( DefaultModel.canBlock() );
113                 
114                 if( itemsAfter.length == itemsBefore.length+1 ) {
115                     int currentIndex = -1;
116                     Node newItem = null;
117                     for( int i=itemsAfter.length-1; i>=0; i-- ) {
118                         newItem = itemsAfter[i];
119                         currentIndex = i;
120                         for( int j=0; j<itemsBefore.length; j++ ) {
121                             if( newItem.equals( itemsBefore[j] ) ) {
122                                 newItem = null;
123                                 break;
124                             }
125                         }
126                         if( null != newItem ) {
127                             break;
128                         }
129                     }
130                     if( null != newItem && dropIndex >= 0 ) {
131                         if( currentIndex < dropIndex )
132                             dropIndex++;
133                         moveItem( targetCategory, newItem.getLookup(), dropIndex );
134                     }
135                 }
136                 return true;
137             }
138         } catch( IOException JavaDoc ioE ) {
139             ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, ioE );
140         } catch( UnsupportedFlavorException JavaDoc e ) {
141             ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e );
142         }
143         return false;
144     }
145     
146     /**
147      * Move palette item to a new position in its current category.
148      *
149      * @param category Lookup of the category that contains the dragged item.
150      * @param itemToMove Lookup of the item that is going to be moved to a new position.
151      * @param moveToIndex Zero-based index to category's children where the item should move to.
152      *
153      * @return True if the move operation was successful.
154      */

155     private boolean moveItem( Lookup category, Lookup itemToMove, int moveToIndex ) {
156         Node categoryNode = (Node)category.lookup( Node.class );
157         if( null == categoryNode )
158             return false;
159         Node itemNode = (Node)itemToMove.lookup( Node.class );
160         if( null == itemNode )
161             return false;
162         
163         Index order = (Index)categoryNode.getCookie( Index.class );
164         if( null == order ) {
165             return false;
166         }
167         
168         int sourceIndex = order.indexOf( itemNode );
169         if( sourceIndex < moveToIndex ) {
170             moveToIndex--;
171         }
172         order.move( sourceIndex, moveToIndex );
173         return true;
174     }
175     
176     /**
177      * @param paletteRoot Lookup of palette's root node.
178      * @return True if it is possible to reorder categories by drag and drop operations.
179      */

180     public boolean canReorderCategories( Lookup paletteRoot ) {
181         Node rootNode = (Node)paletteRoot.lookup( Node.class );
182         if( null != rootNode ) {
183             return null != rootNode.getCookie( Index.class );
184         }
185         return false;
186     }
187     
188     /**
189      * Move the given category to a new position.
190      *
191      * @param category The lookup of category that is being dragged.
192      * @param moveToIndex Zero-based index to palette's root children Nodes
193      * where the category should move to.
194      * @return True if the move operation was successful.
195      */

196     public boolean moveCategory( Lookup category, int moveToIndex ) {
197         Node categoryNode = (Node)category.lookup( Node.class );
198         if( null == categoryNode )
199             return false;
200         Node rootNode = categoryNode.getParentNode();
201         if( null == rootNode )
202             return false;
203         
204         Index order = (Index)rootNode.getCookie( Index.class );
205         if( null == order ) {
206             return false;
207         }
208         
209         int sourceIndex = order.indexOf( categoryNode );
210         if( sourceIndex < moveToIndex ) {
211             moveToIndex--;
212         }
213         order.move( sourceIndex, moveToIndex );
214         return true;
215     }
216     
217     private static final class DefaultDragAndDropHandler extends DragAndDropHandler {
218         public void customize(ExTransferable t, Lookup item) {
219             //do nothing
220
}
221     }
222 }
223
Popular Tags