1 19 20 package org.netbeans.modules.palette.ui; 21 22 import java.awt.Component ; 23 import java.awt.Point ; 24 import java.awt.Rectangle ; 25 import java.awt.datatransfer.Transferable ; 26 import java.awt.dnd.DnDConstants ; 27 import java.awt.dnd.DragGestureEvent ; 28 import java.awt.dnd.DragGestureListener ; 29 import java.awt.dnd.DragGestureRecognizer ; 30 import java.awt.dnd.DragSource ; 31 import java.awt.dnd.DragSourceAdapter ; 32 import java.awt.dnd.DragSourceDropEvent ; 33 import java.awt.dnd.DragSourceListener ; 34 import java.awt.dnd.DropTarget ; 35 import java.awt.dnd.DropTargetDragEvent ; 36 import java.awt.dnd.DropTargetDropEvent ; 37 import java.awt.dnd.DropTargetEvent ; 38 import java.awt.dnd.DropTargetListener ; 39 import java.awt.dnd.InvalidDnDOperationException ; 40 import java.awt.event.ActionEvent ; 41 import java.awt.event.ActionListener ; 42 import java.awt.geom.Line2D ; 43 import java.util.ArrayList ; 44 import java.util.HashSet ; 45 import java.util.Iterator ; 46 import java.util.Set ; 47 import java.util.logging.Level ; 48 import java.util.logging.Logger ; 49 import javax.swing.SwingUtilities ; 50 import javax.swing.Timer ; 51 import org.netbeans.modules.palette.Category; 52 import org.netbeans.modules.palette.Item; 53 54 59 public class DnDSupport implements DragGestureListener , DropTargetListener { 60 61 final static private int DELAY_TIME_FOR_EXPAND = 1000; 62 63 private Set <DragGestureRecognizer > recognizers = new HashSet <DragGestureRecognizer >( 5 ); 64 private Set <DropTarget > dropTargets = new HashSet <DropTarget >( 5 ); 65 66 private Category draggingCategory; 67 private Item draggingItem; 68 private CategoryList dragSourceCategoryList; 69 private Item targetItem; 70 71 private boolean dropBefore; 72 73 private DragSourceListener dragSourceListener; 74 75 private DropGlassPane dropPane; 76 77 private PalettePanel palette; 78 79 private Timer timer; 80 81 private static final Logger ERR = Logger.getLogger("org.netbeans.modules.palette"); 83 84 public DnDSupport( PalettePanel palette ) { 85 this.palette = palette; 86 } 87 88 void add( CategoryDescriptor descriptor ) { 89 CategoryList list = descriptor.getList(); 90 recognizers.add( DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer( list, DnDConstants.ACTION_MOVE, this ) ); 91 dropTargets.add( new DropTarget ( list, this ) ); 92 93 CategoryButton button = descriptor.getButton(); 94 recognizers.add( DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer( button, DnDConstants.ACTION_MOVE, this ) ); 95 dropTargets.add( new DropTarget ( button, this ) ); 96 } 97 98 void remove( CategoryDescriptor descriptor ) { 99 ArrayList <DragGestureRecognizer > recognizersToRemove = new ArrayList <DragGestureRecognizer >( 2 ); 100 for( Iterator <DragGestureRecognizer > i=recognizers.iterator(); i.hasNext(); ) { 101 DragGestureRecognizer dgr = i.next(); 102 if( dgr.getComponent() == descriptor.getButton() 103 || dgr.getComponent() == descriptor.getList() ) { 104 recognizersToRemove.add( dgr ); 105 dgr.removeDragGestureListener( this ); 106 } 107 } 108 recognizers.removeAll( recognizersToRemove ); 109 110 ArrayList <DropTarget > dropTargetsToRemove = new ArrayList <DropTarget >( 2 ); 111 for( Iterator <DropTarget > i=dropTargets.iterator(); i.hasNext(); ) { 112 DropTarget dt = i.next(); 113 if( dt.getComponent() == descriptor.getButton() 114 || dt.getComponent() == descriptor.getList() ) { 115 dropTargetsToRemove.add( dt ); 116 dt.removeDropTargetListener( this ); 117 } 118 } 119 dropTargets.removeAll( dropTargetsToRemove ); 120 } 121 122 public void dragGestureRecognized( DragGestureEvent dge ) { 123 Transferable t = null; 124 125 if( dge.getComponent() instanceof CategoryButton ) { 126 CategoryButton button = (CategoryButton)dge.getComponent(); 128 draggingCategory = button.getCategory(); 129 t = draggingCategory.getTransferable(); 130 131 } else if( dge.getComponent() instanceof CategoryList ) { 132 CategoryList list = (CategoryList)dge.getComponent(); 134 int selIndex = list.locationToIndex( dge.getDragOrigin() ); 135 draggingItem = list.getItemAt( selIndex ); 136 if( null == draggingItem ) { 137 return; 138 } 139 t = draggingItem.drag(); 140 dragSourceCategoryList = list; 141 } 142 if( null != t ) { 143 dge.getDragSource().addDragSourceListener( getDragSourceListener() ); 144 try { 145 dge.startDrag( null, t ); 146 } catch( InvalidDnDOperationException idndE ) { 147 ERR.log( Level.INFO, idndE.getMessage(), idndE ); 148 } 149 } 150 } 151 152 public void drop( DropTargetDropEvent dtde ) { 153 Component target = dtde.getDropTargetContext().getComponent(); 154 Category targetCategory = null; 155 if( target instanceof CategoryList ) { 156 targetCategory = ((CategoryList)target).getCategory(); 157 } else if( target instanceof CategoryButton ) { 158 targetCategory = ((CategoryButton)target).getCategory(); 159 } 160 if( null != draggingCategory ) { 161 boolean res = false; 163 if( null != targetCategory && (target instanceof CategoryButton) ) { 164 res = palette.getModel().moveCategory( draggingCategory, targetCategory, dropBefore ); 165 } 166 dtde.dropComplete( res ); 167 } else { 168 dtde.acceptDrop( dtde.getDropAction() ); 171 boolean res = false; 172 if( null != targetCategory ) { 173 Transferable t; 174 if( null != draggingItem ) { 175 t = draggingItem.cut(); 177 } else { 178 t = dtde.getTransferable(); 180 } 181 res = targetCategory.dropItem( t, dtde.getDropAction(), targetItem, dropBefore ); 182 } 183 dtde.dropComplete( res ); 184 } 185 cleanupAfterDnD(); 186 } 187 188 public void dragExit( DropTargetEvent dte ) { 189 removeDropLine(); 190 if (DropGlassPane.isOriginalPaneStored()) { 191 DropGlassPane.putBackOriginal(); 192 } 193 removeTimer(); 194 } 195 196 public void dropActionChanged( DropTargetDragEvent dtde ) { 197 } 198 199 public void dragOver( DropTargetDragEvent dtde ) { 200 checkStoredGlassPane(); 201 202 doDragOver( dtde ); 203 } 204 205 public void dragEnter( DropTargetDragEvent dtde ) { 206 checkStoredGlassPane(); 207 208 Component target = dtde.getDropTargetContext().getComponent(); 209 if( target instanceof CategoryButton && null == draggingCategory ) { 210 final CategoryButton button = (CategoryButton)target; 211 if( !button.isSelected() && (null == timer || !timer.isRunning()) ) { 212 removeTimer(); 213 timer = new Timer ( 214 DELAY_TIME_FOR_EXPAND, 215 new ActionListener () { 216 final public void actionPerformed(ActionEvent e) { 217 button.setExpanded( true ); 218 } 219 } 220 ); 221 timer.setRepeats(false); 222 timer.start(); 223 } 224 } 225 doDragOver( dtde ); 226 } 227 228 229 230 private void removeTimer() { 231 if (timer != null) { 232 ActionListener [] l = (ActionListener []) timer.getListeners(ActionListener .class); 233 234 for (int i = 0; i < l.length; i++) { 235 timer.removeActionListener(l[i]); 236 } 237 238 timer.stop(); 239 timer = null; 240 } 241 } 242 243 244 private void doDragOver( DropTargetDragEvent dtde ) { 245 Component target = dtde.getDropTargetContext().getComponent(); 246 if( null != draggingCategory ) { 247 Category targetCategory = null; 249 if( target instanceof CategoryButton ) { 250 CategoryButton button = (CategoryButton)target; 251 targetCategory = button.getCategory(); 252 } 253 if( null == targetCategory || !palette.getModel().canReorderCategories() ) { 254 dtde.rejectDrag(); 255 removeDropLine(); 256 return; 257 } 258 dropBefore = dtde.getLocation().y < (target.getHeight()/2); 259 Point p1 = target.getLocation(); 260 Point p2 = target.getLocation(); 261 p2.x += target.getWidth(); 262 if( !dropBefore ) { 263 p1.y += target.getHeight(); 264 p2.y += target.getHeight(); 265 } 266 p1 = SwingUtilities.convertPoint( target, p1, palette.getRootPane() ); 267 p2 = SwingUtilities.convertPoint( target, p2, palette.getRootPane() ); 268 Line2D line = new Line2D.Double ( p1.x, p1.y, p2.x, p2.y ); 269 dropPane.setDropLine( line ); 270 } else { 271 Category targetCategory = null; 274 if( target instanceof CategoryList ) { 275 CategoryList list = (CategoryList)target; 276 targetCategory = list.getCategory(); 277 } else if( target instanceof CategoryButton ) { 278 CategoryButton button = (CategoryButton)target; 279 targetCategory = button.getCategory(); 280 } 281 if( null != targetCategory && targetCategory.dragOver( dtde ) ) { 282 dtde.acceptDrag( dtde.getDropAction() ); 283 } else { 284 dtde.rejectDrag(); 285 removeDropLine(); 286 targetItem = null; 287 return; 288 } 289 290 if( target instanceof CategoryList ) { 291 CategoryList list = (CategoryList)target; 292 int dropIndex = list.locationToIndex( dtde.getLocation() ); 293 if( dropIndex < 0 ) { 294 dropPane.setDropLine( null ); 295 targetItem = null; 296 } else { 297 boolean verticalDropBar = list.getColumnCount() > 1; 298 Rectangle rect = list.getCellBounds( dropIndex, dropIndex ); 299 if( verticalDropBar ) 300 dropBefore = dtde.getLocation().x < (rect.x + rect.width/2); 301 else 302 dropBefore = dtde.getLocation().y < (rect.y + rect.height/2); 303 Point p1 = rect.getLocation(); 304 Point p2 = rect.getLocation(); 305 if( verticalDropBar ) { 306 p2.y += rect.height; 307 if( !dropBefore ) { 308 p1.x += rect.width; 309 p2.x += rect.width; 310 } 311 } else { 312 p2.x += rect.width; 313 if( !dropBefore ) { 314 p1.y += rect.height; 315 p2.y += rect.height; 316 } 317 } 318 p1 = SwingUtilities.convertPoint( list, p1, palette.getRootPane() ); 319 p2 = SwingUtilities.convertPoint( list, p2, palette.getRootPane() ); 320 Line2D line = new Line2D.Double ( p1.x, p1.y, p2.x, p2.y ); 321 dropPane.setDropLine( line ); 322 targetItem = (Item)list.getModel().getElementAt( dropIndex ); 323 } 324 } else { 325 targetItem = null; 326 dropBefore = false; 327 } 328 } 329 } 331 332 private DragSourceListener getDragSourceListener() { 333 if( null == dragSourceListener ) { 334 dragSourceListener = new DragSourceAdapter () { 335 public void dragDropEnd( DragSourceDropEvent dsde ) { 336 dsde.getDragSourceContext().getDragSource().removeDragSourceListener( this ); 337 cleanupAfterDnD(); 338 } 339 }; 340 } 341 return dragSourceListener; 342 } 343 344 private void cleanupAfterDnD() { 345 draggingItem = null; 346 draggingCategory = null; 347 targetItem = null; 348 if( null != dragSourceCategoryList ) { 349 dragSourceCategoryList.resetRollover(); 350 } 351 dragSourceCategoryList = null; 352 removeDropLine(); 353 if (DropGlassPane.isOriginalPaneStored()) { 354 DropGlassPane.putBackOriginal(); 355 } 356 removeTimer(); 357 } 358 359 private void checkStoredGlassPane() { 360 if( !DropGlassPane.isOriginalPaneStored() ) { 362 Component comp = palette.getRootPane().getGlassPane(); 363 DropGlassPane.setOriginalPane( palette, comp, comp.isVisible() ); 364 365 dropPane = DropGlassPane.getDefault( palette ); 367 palette.getRootPane().setGlassPane( dropPane ); 368 dropPane.revalidate(); 369 dropPane.validate(); 370 dropPane.setVisible(true); 371 } 372 } 373 374 private void removeDropLine() { 375 if( null != dropPane ) 376 dropPane.setDropLine( null ); 377 } 378 } 379 | Popular Tags |