1 /* 2 * Copyright (c) 2009, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * AWT Button is a DragSource and also a transferable object 26 */ 27 28 import java.awt.*; 29 import java.awt.datatransfer.*; 30 31 import java.awt.image.ImageConsumer; 32 import java.awt.image.MemoryImageSource; 33 34 import java.awt.dnd.*; 35 import java.io.*; 36 37 class DnDSource extends Button implements Transferable, 38 DragGestureListener, 39 DragSourceListener { 40 private DataFlavor df; 41 private transient int dropAction; 42 private final int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK; 43 DragSource dragSource = new DragSource(); 44 45 DnDSource(String label) { 46 super(label); 47 setBackground(Color.yellow); 48 setForeground(Color.blue); 49 df = new DataFlavor(DnDSource.class, "DnDSource"); 50 51 dragSource.createDefaultDragGestureRecognizer( 52 this, 53 dragOperation, 54 this 55 ); 56 dragSource.addDragSourceListener(this); 57 } 58 59 public void changeCursor( 60 DragSourceContext dsc, 61 int ra 62 ) { 63 java.awt.Cursor c = null; 64 if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK) 65 c = DragSource.DefaultLinkDrop; 66 else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE) 67 c = MyCursor.MOVE;//DragSource.DefaultMoveDrop; 68 else if ((ra & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY) 69 c = MyCursor.COPY; 70 else 71 c = MyCursor.NO_DROP; 72 dsc.setCursor(c); 73 } 74 75 /** 76 * a Drag gesture has been recognized 77 */ 78 int iProblem = 0; 79 String[] problem = {"unready", "throw exeption", "good"}; 80 public void dragGestureRecognized(DragGestureEvent dge) { 81 System.out.println("starting Drag"); 82 if( !DragSource.isDragImageSupported() ) { 83 dge.startDrag( 84 null, 85 this, 86 this); 87 } else { 88 setLabel("Drag ME! (with " + problem[iProblem] + " image)"); 89 int w = 100; 90 int h = 100; 91 int pix[] = new int[w * h]; 92 int index = 0; 93 for (int y = 0; y < h; y++) { 94 int red = (y * 255) / (h - 1); 95 for (int x = 0; x < w; x++) { 96 int blue = (x * 255) / (w - 1); 97 pix[index++] = (255 << 24) | (red << 16) | blue; 98 } 99 } 100 try{ 101 dge.startDrag( 102 null, 103 Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(w, h, pix, 0, w) 104 { 105 @Override 106 public void startProduction(ImageConsumer ic) 107 { 108 switch(iProblem){ 109 case 0: 110 //incomplite 111 break; 112 case 1: 113 //exception 114 throw new RuntimeException("test exception 1"); 115 default: 116 super.startProduction(ic); 117 break; 118 } 119 } 120 } 121 ), 122 new Point(15, 40) { 123 @Override 124 public double getX() { 125 if(2==iProblem){ 126 //never happen 127 throw new RuntimeException("test exception 2"); 128 } 129 return x; 130 } 131 @Override 132 public Point getLocation(){ 133 //never happen 134 throw new RuntimeException("test exception 3"); 135 } 136 }, 137 this, 138 this); 139 }catch(InvalidDnDOperationException e){ 140 if( iProblem<=2 ){ 141 System.err.println("good exception: " + e.getMessage() ); 142 } else { 143 System.err.println("bad exception"); 144 e.printStackTrace(); 145 throw new RuntimeException(e.getMessage()); 146 } 147 } finally { 148 ++iProblem; 149 } 150 } 151 } 152 153 /** 154 * as the hotspot enters a platform dependent drop site 155 */ 156 157 public void dragEnter(DragSourceDragEvent dsde) { 158 System.out.println("[Source] dragEnter"); 159 changeCursor( 160 dsde.getDragSourceContext(), 161 dsde.getUserAction() & dsde.getDropAction() 162 ); 163 } 164 165 /** 166 * as the hotspot moves over a platform dependent drop site 167 */ 168 public void dragOver(DragSourceDragEvent dsde) { 169 System.out.println("[Source] dragOver"); 170 changeCursor( 171 dsde.getDragSourceContext(), 172 dsde.getUserAction() & dsde.getDropAction() 173 ); 174 dropAction = dsde.getUserAction() & dsde.getDropAction(); 175 System.out.println("dropAction = " + dropAction); 176 } 177 178 /** 179 * as the hotspot exits a platform dependent drop site 180 */ 181 public void dragExit(DragSourceEvent dse) { 182 System.out.println("[Source] dragExit"); 183 changeCursor( 184 dse.getDragSourceContext(), 185 DnDConstants.ACTION_NONE 186 ); 187 } 188 189 /** 190 * as the operation changes 191 */ 192 public void dragGestureChanged(DragSourceDragEvent dsde) { 193 System.out.println("[Source] dragGestureChanged"); 194 changeCursor( 195 dsde.getDragSourceContext(), 196 dsde.getUserAction() & dsde.getDropAction() 197 ); 198 dropAction = dsde.getUserAction() & dsde.getDropAction(); 199 System.out.println("dropAction = " + dropAction); 200 } 201 202 203 /** 204 * as the operation completes 205 */ 206 public void dragDropEnd(DragSourceDropEvent dsde) { 207 System.out.println("[Source] dragDropEnd"); 208 } 209 210 public void dropActionChanged(DragSourceDragEvent dsde) { 211 System.out.println("[Source] dropActionChanged"); 212 dropAction = dsde.getUserAction() & dsde.getDropAction(); 213 System.out.println("dropAction = " + dropAction); 214 } 215 216 public DataFlavor[] getTransferDataFlavors() { 217 return new DataFlavor[]{df}; 218 } 219 220 public boolean isDataFlavorSupported(DataFlavor sdf) { 221 return df.equals(sdf); 222 } 223 224 public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException { 225 Object copy = null; 226 if( !df.equals(tdf) ){ 227 throw new UnsupportedFlavorException(tdf); 228 } 229 Container parent = getParent(); 230 switch (dropAction) { 231 case DnDConstants.ACTION_COPY: 232 try { 233 copy = this.clone(); 234 } catch (CloneNotSupportedException e) { 235 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 236 ObjectOutputStream oos = new ObjectOutputStream(baos); 237 238 oos.writeObject(this); 239 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 240 ObjectInputStream ois = new ObjectInputStream(bais); 241 try { 242 copy = ois.readObject(); 243 } catch (ClassNotFoundException cnfe) { 244 // do nothing 245 } 246 } 247 parent.add(this); 248 return copy; 249 250 case DnDConstants.ACTION_MOVE: 251 synchronized (this) { 252 if (parent != null) { 253 parent.remove(this); 254 Label label = new Label("[empty]"); 255 label.setBackground(Color.cyan); 256 label.setBounds(this.getBounds()); 257 parent.add(label); 258 } 259 } 260 return this; 261 262 case DnDConstants.ACTION_LINK: 263 return this; 264 265 default: 266 return null; 267 } 268 269 } 270 } 271