1: /* DragSourceContext.java -- 2: Copyright (C) 2002 Free Software Foundation 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.awt.dnd; 40: 41: import java.awt.Component; 42: import java.awt.Cursor; 43: import java.awt.Image; 44: import java.awt.Point; 45: import java.awt.datatransfer.Transferable; 46: import java.awt.dnd.peer.DragSourceContextPeer; 47: import java.io.Serializable; 48: import java.util.TooManyListenersException; 49: 50: /** 51: * @since 1.2 52: */ 53: public class DragSourceContext 54: implements DragSourceListener, DragSourceMotionListener, Serializable 55: { 56: /** 57: * Compatible with JDK 1.2+ 58: */ 59: static final long serialVersionUID = -115407898692194719L; 60: 61: protected static final int DEFAULT = 0; 62: protected static final int ENTER = 1; 63: protected static final int OVER = 2; 64: protected static final int CHANGED = 3; 65: 66: private DragSourceContextPeer peer; 67: private Cursor cursor; 68: private Transferable transferable; 69: private DragGestureEvent trigger; 70: private DragSourceListener dragSourceListener; 71: private boolean useCustomCursor; 72: private int sourceActions; 73: private Image image; 74: private Point offset; 75: 76: /** 77: * Initializes a drag source context. 78: * 79: * @exception IllegalArgumentException If Component or DragSource of trigger 80: * are null, the drag action for the trigger event is DnDConstants.ACTION_NONE 81: * or if the source actions for the DragGestureRecognizer associated with the 82: * trigger event are equal to DnDConstants.ACTION_NONE. 83: * @exception NullPointerException If peer, trans or trigger is null or if the 84: * image is not null but the offset is. 85: */ 86: public DragSourceContext (DragSourceContextPeer peer, 87: DragGestureEvent trigger, Cursor cursor, 88: Image image, Point offset, Transferable trans, 89: DragSourceListener dsl) 90: { 91: if (peer == null 92: || trigger == null || trans == null 93: || (image != null && offset == null)) 94: throw new NullPointerException (); 95: 96: if (trigger.getComponent () == null 97: || trigger.getDragSource () == null 98: || trigger.getDragAction () == DnDConstants.ACTION_NONE 99: || trigger.getSourceAsDragGestureRecognizer () 100: .getSourceActions () == DnDConstants.ACTION_NONE) 101: throw new IllegalArgumentException (); 102: 103: this.peer = peer; 104: this.trigger = trigger; 105: this.cursor = cursor; 106: this.image = image; 107: this.offset = offset; 108: this.transferable = trans; 109: this.dragSourceListener = dsl; 110: this.sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions(); 111: 112: setCursor(cursor); 113: updateCurrentCursor(trigger.getDragAction(), sourceActions, DEFAULT); 114: } 115: 116: /** 117: * Returns the DragSource object associated with the 118: * DragGestureEvent. 119: * 120: * @return the DragSource associated with the trigger. 121: */ 122: public DragSource getDragSource() 123: { 124: return trigger.getDragSource (); 125: } 126: 127: /** 128: * Returns the component associated with this. 129: * 130: * @return the component associated with the trigger. 131: */ 132: public Component getComponent() 133: { 134: return trigger.getComponent (); 135: } 136: 137: /** 138: * Gets the trigger associated with this. 139: * 140: * @return the trigger. 141: */ 142: public DragGestureEvent getTrigger() 143: { 144: return trigger; 145: } 146: 147: /** 148: * Returns the source actions for the DragGestureRecognizer. 149: * 150: * @return the source actions for DragGestureRecognizer. 151: */ 152: public int getSourceActions() 153: { 154: if (sourceActions == 0) 155: sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions(); 156: return sourceActions; 157: } 158: 159: /** 160: * Sets the cursor for this drag operation to the specified cursor. 161: * 162: * @param cursor c - the Cursor to use, or null to use the default drag 163: * cursor. 164: */ 165: public void setCursor(Cursor cursor) 166: { 167: if (cursor == null) 168: useCustomCursor = false; 169: else 170: useCustomCursor = true; 171: this.cursor = cursor; 172: peer.setCursor(cursor); 173: } 174: 175: /** 176: * Returns the current cursor or null if the default 177: * drag cursor is used. 178: * 179: * @return the current cursor or null. 180: */ 181: public Cursor getCursor() 182: { 183: return cursor; 184: } 185: 186: /** 187: * Adds a <code>DragSourceListener</code>. 188: * 189: * @exception TooManyListenersException If a <code>DragSourceListener</code> 190: * has already been added. 191: */ 192: public void addDragSourceListener (DragSourceListener dsl) 193: throws TooManyListenersException 194: { 195: if (dragSourceListener != null) 196: throw new TooManyListenersException (); 197: 198: dragSourceListener = dsl; 199: } 200: 201: public void removeDragSourceListener (DragSourceListener dsl) 202: { 203: if (dragSourceListener == dsl) 204: dragSourceListener = null; 205: } 206: 207: /** 208: * This function tells the peer that the DataFlavors have been modified. 209: */ 210: public void transferablesFlavorsChanged() 211: { 212: peer.transferablesFlavorsChanged(); 213: } 214: 215: /** 216: * Calls dragEnter on the listeners registered with this 217: * and with the DragSource. 218: * 219: * @param e - the DragSourceDragEvent 220: */ 221: public void dragEnter(DragSourceDragEvent e) 222: { 223: if (dragSourceListener != null) 224: dragSourceListener.dragEnter(e); 225: 226: DragSource ds = getDragSource(); 227: DragSourceListener[] dsl = ds.getDragSourceListeners(); 228: for (int i = 0; i < dsl.length; i++) 229: dsl[i].dragEnter(e); 230: 231: updateCurrentCursor(e.getDropAction(), e.getTargetActions(), ENTER); 232: } 233: 234: /** 235: * Calls dragOver on the listeners registered with this 236: * and with the DragSource. 237: * 238: * @param e - the DragSourceDragEvent 239: */ 240: public void dragOver(DragSourceDragEvent e) 241: { 242: if (dragSourceListener != null) 243: dragSourceListener.dragOver(e); 244: 245: DragSource ds = getDragSource(); 246: DragSourceListener[] dsl = ds.getDragSourceListeners(); 247: for (int i = 0; i < dsl.length; i++) 248: dsl[i].dragOver(e); 249: 250: updateCurrentCursor(e.getDropAction(), e.getTargetActions(), OVER); 251: } 252: 253: /** 254: * Calls dragExit on the listeners registered with this 255: * and with the DragSource. 256: * 257: * @param e - the DragSourceEvent 258: */ 259: public void dragExit(DragSourceEvent e) 260: { 261: if (dragSourceListener != null) 262: dragSourceListener.dragExit(e); 263: 264: DragSource ds = getDragSource(); 265: DragSourceListener[] dsl = ds.getDragSourceListeners(); 266: for (int i = 0; i < dsl.length; i++) 267: dsl[i].dragExit(e); 268: 269: updateCurrentCursor(DnDConstants.ACTION_NONE, DnDConstants.ACTION_NONE, 270: DEFAULT); 271: } 272: 273: /** 274: * Calls dropActionChanged on the listeners registered with this 275: * and with the DragSource. 276: * 277: * @param e - the DragSourceDragEvent 278: */ 279: public void dropActionChanged(DragSourceDragEvent e) 280: { 281: if (dragSourceListener != null) 282: dragSourceListener.dropActionChanged(e); 283: 284: DragSource ds = getDragSource(); 285: DragSourceListener[] dsl = ds.getDragSourceListeners(); 286: for (int i = 0; i < dsl.length; i++) 287: dsl[i].dropActionChanged(e); 288: 289: updateCurrentCursor(e.getDropAction(), e.getTargetActions(), CHANGED); 290: } 291: 292: /** 293: * Calls dragDropEnd on the listeners registered with this 294: * and with the DragSource. 295: * 296: * @param e - the DragSourceDropEvent 297: */ 298: public void dragDropEnd(DragSourceDropEvent e) 299: { 300: if (dragSourceListener != null) 301: dragSourceListener.dragDropEnd(e); 302: 303: DragSource ds = getDragSource(); 304: DragSourceListener[] dsl = ds.getDragSourceListeners(); 305: for (int i = 0; i < dsl.length; i++) 306: dsl[i].dragDropEnd(e); 307: } 308: 309: /** 310: * Calls dragMouseMoved on the listeners registered with the DragSource. 311: * 312: * @param e - the DragSourceDragEvent 313: */ 314: public void dragMouseMoved(DragSourceDragEvent e) 315: { 316: DragSource ds = getDragSource(); 317: DragSourceMotionListener[] dsml = ds.getDragSourceMotionListeners(); 318: for (int i = 0; i < dsml.length; i++) 319: dsml[i].dragMouseMoved(e); 320: } 321: 322: /** 323: * Returns the Transferable set with this object. 324: * 325: * @return the transferable. 326: */ 327: public Transferable getTransferable() 328: { 329: return transferable; 330: } 331: 332: /** 333: * This function sets the drag cursor for the specified operation, actions and 334: * status if the default drag cursor is active. Otherwise, the cursor is not 335: * updated in any way. 336: * 337: * @param dropOp - the current operation. 338: * @param targetAct - the supported actions. 339: * @param status - the status of the cursor (constant). 340: */ 341: protected void updateCurrentCursor(int dropOp, int targetAct, int status) 342: { 343: if (! useCustomCursor) 344: { 345: Cursor newCursor = null; 346: switch (status) 347: { 348: default: 349: targetAct = DnDConstants.ACTION_NONE; 350: case ENTER: 351: case CHANGED: 352: case OVER: 353: int action = dropOp & targetAct; 354: if (action == DnDConstants.ACTION_NONE) 355: { 356: if ((dropOp & DnDConstants.ACTION_LINK) != 0) 357: newCursor = DragSource.DefaultLinkNoDrop; 358: else if ((dropOp & DnDConstants.ACTION_MOVE) != 0) 359: newCursor = DragSource.DefaultMoveNoDrop; 360: else 361: newCursor = DragSource.DefaultCopyNoDrop; 362: } 363: else 364: { 365: if ((dropOp & DnDConstants.ACTION_LINK) != 0) 366: newCursor = DragSource.DefaultLinkDrop; 367: else if ((dropOp & DnDConstants.ACTION_MOVE) != 0) 368: newCursor = DragSource.DefaultMoveDrop; 369: else 370: newCursor = DragSource.DefaultCopyDrop; 371: } 372: } 373: 374: if (cursor == null || ! cursor.equals(newCursor)) 375: { 376: cursor = newCursor; 377: DragSourceContextPeer p = peer; 378: if (p != null) 379: p.setCursor(cursor); 380: } 381: } 382: } 383: } // class DragSourceContext