1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt.dnd; 27 28 import java.awt.event.InputEvent; 29 30 /** 31 * The {@code DragSourceDragEvent} is 32 * delivered from the {@code DragSourceContextPeer}, 33 * via the {@code DragSourceContext}, to the {@code DragSourceListener} 34 * registered with that {@code DragSourceContext} and with its associated 35 * {@code DragSource}. 36 * <p> 37 * The {@code DragSourceDragEvent} reports the <i>target drop action</i> 38 * and the <i>user drop action</i> that reflect the current state of 39 * the drag operation. 40 * <p> 41 * <i>Target drop action</i> is one of {@code DnDConstants} that represents 42 * the drop action selected by the current drop target if this drop action is 43 * supported by the drag source or {@code DnDConstants.ACTION_NONE} if this 44 * drop action is not supported by the drag source. 45 * <p> 46 * <i>User drop action</i> depends on the drop actions supported by the drag 47 * source and the drop action selected by the user. The user can select a drop 48 * action by pressing modifier keys during the drag operation: 49 * <pre> 50 * Ctrl + Shift -> ACTION_LINK 51 * Ctrl -> ACTION_COPY 52 * Shift -> ACTION_MOVE 53 * </pre> 54 * If the user selects a drop action, the <i>user drop action</i> is one of 55 * {@code DnDConstants} that represents the selected drop action if this 56 * drop action is supported by the drag source or 57 * {@code DnDConstants.ACTION_NONE} if this drop action is not supported 58 * by the drag source. 59 * <p> 60 * If the user doesn't select a drop action, the set of 61 * {@code DnDConstants} that represents the set of drop actions supported 62 * by the drag source is searched for {@code DnDConstants.ACTION_MOVE}, 63 * then for {@code DnDConstants.ACTION_COPY}, then for 64 * {@code DnDConstants.ACTION_LINK} and the <i>user drop action</i> is the 65 * first constant found. If no constant is found the <i>user drop action</i> 66 * is {@code DnDConstants.ACTION_NONE}. 67 * 68 * @since 1.2 69 * 70 */ 71 72 public class DragSourceDragEvent extends DragSourceEvent { 73 74 private static final long serialVersionUID = 481346297933902471L; 75 76 /** 77 * Constructs a {@code DragSourceDragEvent}. 78 * This class is typically 79 * instantiated by the {@code DragSourceContextPeer} 80 * rather than directly 81 * by client code. 82 * The coordinates for this {@code DragSourceDragEvent} 83 * are not specified, so {@code getLocation} will return 84 * {@code null} for this event. 85 * <p> 86 * The arguments {@code dropAction} and {@code action} should 87 * be one of {@code DnDConstants} that represents a single action. 88 * The argument {@code modifiers} should be either a bitwise mask 89 * of old {@code java.awt.event.InputEvent.*_MASK} constants or a 90 * bitwise mask of extended {@code java.awt.event.InputEvent.*_DOWN_MASK} 91 * constants. 92 * This constructor does not throw any exception for invalid {@code dropAction}, 93 * {@code action} and {@code modifiers}. 94 * 95 * @param dsc the {@code DragSourceContext} that is to manage 96 * notifications for this event. 97 * @param dropAction the user drop action. 98 * @param action the target drop action. 99 * @param modifiers the modifier keys down during event (shift, ctrl, 100 * alt, meta) 101 * Either extended _DOWN_MASK or old _MASK modifiers 102 * should be used, but both models should not be mixed 103 * in one event. Use of the extended modifiers is 104 * preferred. 105 * 106 * @throws IllegalArgumentException if {@code dsc} is {@code null}. 107 * 108 * @see java.awt.event.InputEvent 109 * @see DragSourceEvent#getLocation 110 */ 111 112 public DragSourceDragEvent(DragSourceContext dsc, int dropAction, 113 int action, int modifiers) { 114 super(dsc); 115 116 targetActions = action; 117 gestureModifiers = modifiers; 118 this.dropAction = dropAction; 119 if ((modifiers & ~(JDK_1_3_MODIFIERS | JDK_1_4_MODIFIERS)) != 0) { 120 invalidModifiers = true; 121 } else if ((getGestureModifiers() != 0) && (getGestureModifiersEx() == 0)) { 122 setNewModifiers(); 123 } else if ((getGestureModifiers() == 0) && (getGestureModifiersEx() != 0)) { 124 setOldModifiers(); 125 } else { 126 invalidModifiers = true; 127 } 128 } 129 130 /** 131 * Constructs a {@code DragSourceDragEvent} given the specified 132 * {@code DragSourceContext}, user drop action, target drop action, 133 * modifiers and coordinates. 134 * <p> 135 * The arguments {@code dropAction} and {@code action} should 136 * be one of {@code DnDConstants} that represents a single action. 137 * The argument {@code modifiers} should be either a bitwise mask 138 * of old {@code java.awt.event.InputEvent.*_MASK} constants or a 139 * bitwise mask of extended {@code java.awt.event.InputEvent.*_DOWN_MASK} 140 * constants. 141 * This constructor does not throw any exception for invalid {@code dropAction}, 142 * {@code action} and {@code modifiers}. 143 * 144 * @param dsc the {@code DragSourceContext} associated with this 145 * event. 146 * @param dropAction the user drop action. 147 * @param action the target drop action. 148 * @param modifiers the modifier keys down during event (shift, ctrl, 149 * alt, meta) 150 * Either extended _DOWN_MASK or old _MASK modifiers 151 * should be used, but both models should not be mixed 152 * in one event. Use of the extended modifiers is 153 * preferred. 154 * @param x the horizontal coordinate for the cursor location 155 * @param y the vertical coordinate for the cursor location 156 * 157 * @throws IllegalArgumentException if {@code dsc} is {@code null}. 158 * 159 * @see java.awt.event.InputEvent 160 * @since 1.4 161 */ 162 public DragSourceDragEvent(DragSourceContext dsc, int dropAction, 163 int action, int modifiers, int x, int y) { 164 super(dsc, x, y); 165 166 targetActions = action; 167 gestureModifiers = modifiers; 168 this.dropAction = dropAction; 169 if ((modifiers & ~(JDK_1_3_MODIFIERS | JDK_1_4_MODIFIERS)) != 0) { 170 invalidModifiers = true; 171 } else if ((getGestureModifiers() != 0) && (getGestureModifiersEx() == 0)) { 172 setNewModifiers(); 173 } else if ((getGestureModifiers() == 0) && (getGestureModifiersEx() != 0)) { 174 setOldModifiers(); 175 } else { 176 invalidModifiers = true; 177 } 178 } 179 180 /** 181 * This method returns the target drop action. 182 * 183 * @return the target drop action. 184 */ 185 public int getTargetActions() { 186 return targetActions; 187 } 188 189 190 private static final int JDK_1_3_MODIFIERS = InputEvent.SHIFT_DOWN_MASK - 1; 191 private static final int JDK_1_4_MODIFIERS = 192 ((InputEvent.ALT_GRAPH_DOWN_MASK << 1) - 1) & ~JDK_1_3_MODIFIERS; 193 194 /** 195 * This method returns an {@code int} representing 196 * the current state of the input device modifiers 197 * associated with the user's gesture. Typically these 198 * would be mouse buttons or keyboard modifiers. 199 * <P> 200 * If the {@code modifiers} passed to the constructor 201 * are invalid, this method returns them unchanged. 202 * 203 * @return the current state of the input device modifiers 204 */ 205 206 public int getGestureModifiers() { 207 return invalidModifiers ? gestureModifiers : gestureModifiers & JDK_1_3_MODIFIERS; 208 } 209 210 /** 211 * This method returns an {@code int} representing 212 * the current state of the input device extended modifiers 213 * associated with the user's gesture. 214 * See {@link InputEvent#getModifiersEx} 215 * <P> 216 * If the {@code modifiers} passed to the constructor 217 * are invalid, this method returns them unchanged. 218 * 219 * @return the current state of the input device extended modifiers 220 * @since 1.4 221 */ 222 223 public int getGestureModifiersEx() { 224 return invalidModifiers ? gestureModifiers : gestureModifiers & JDK_1_4_MODIFIERS; 225 } 226 227 /** 228 * This method returns the user drop action. 229 * 230 * @return the user drop action. 231 */ 232 public int getUserAction() { return dropAction; } 233 234 /** 235 * This method returns the logical intersection of 236 * the target drop action and the set of drop actions supported by 237 * the drag source. 238 * 239 * @return the logical intersection of the target drop action and 240 * the set of drop actions supported by the drag source. 241 */ 242 public int getDropAction() { 243 return targetActions & getDragSourceContext().getSourceActions(); 244 } 245 246 /* 247 * fields 248 */ 249 250 /** 251 * The target drop action. 252 * 253 * @serial 254 */ 255 private int targetActions = DnDConstants.ACTION_NONE; 256 257 /** 258 * The user drop action. 259 * 260 * @serial 261 */ 262 private int dropAction = DnDConstants.ACTION_NONE; 263 264 /** 265 * The state of the input device modifiers associated with the user 266 * gesture. 267 * 268 * @serial 269 */ 270 private int gestureModifiers = 0; 271 272 /** 273 * Indicates whether the {@code gestureModifiers} are invalid. 274 * 275 * @serial 276 */ 277 private boolean invalidModifiers; 278 279 /** 280 * Sets new modifiers by the old ones. 281 * The mouse modifiers have higher priority than overlaying key 282 * modifiers. 283 */ 284 private void setNewModifiers() { 285 if ((gestureModifiers & InputEvent.BUTTON1_MASK) != 0) { 286 gestureModifiers |= InputEvent.BUTTON1_DOWN_MASK; 287 } 288 if ((gestureModifiers & InputEvent.BUTTON2_MASK) != 0) { 289 gestureModifiers |= InputEvent.BUTTON2_DOWN_MASK; 290 } 291 if ((gestureModifiers & InputEvent.BUTTON3_MASK) != 0) { 292 gestureModifiers |= InputEvent.BUTTON3_DOWN_MASK; 293 } 294 if ((gestureModifiers & InputEvent.SHIFT_MASK) != 0) { 295 gestureModifiers |= InputEvent.SHIFT_DOWN_MASK; 296 } 297 if ((gestureModifiers & InputEvent.CTRL_MASK) != 0) { 298 gestureModifiers |= InputEvent.CTRL_DOWN_MASK; 299 } 300 if ((gestureModifiers & InputEvent.ALT_GRAPH_MASK) != 0) { 301 gestureModifiers |= InputEvent.ALT_GRAPH_DOWN_MASK; 302 } 303 } 304 305 /** 306 * Sets old modifiers by the new ones. 307 */ 308 private void setOldModifiers() { 309 if ((gestureModifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) { 310 gestureModifiers |= InputEvent.BUTTON1_MASK; 311 } 312 if ((gestureModifiers & InputEvent.BUTTON2_DOWN_MASK) != 0) { 313 gestureModifiers |= InputEvent.BUTTON2_MASK; 314 } 315 if ((gestureModifiers & InputEvent.BUTTON3_DOWN_MASK) != 0) { 316 gestureModifiers |= InputEvent.BUTTON3_MASK; 317 } 318 if ((gestureModifiers & InputEvent.SHIFT_DOWN_MASK) != 0) { 319 gestureModifiers |= InputEvent.SHIFT_MASK; 320 } 321 if ((gestureModifiers & InputEvent.CTRL_DOWN_MASK) != 0) { 322 gestureModifiers |= InputEvent.CTRL_MASK; 323 } 324 if ((gestureModifiers & InputEvent.ALT_GRAPH_DOWN_MASK) != 0) { 325 gestureModifiers |= InputEvent.ALT_GRAPH_MASK; 326 } 327 } 328 }