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.  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 /*
  27 *  AWT Button is a DragSource and also a transferable object
  28 */
  29 
  30 import java.awt.*;
  31 import java.awt.datatransfer.*;
  32 import java.awt.dnd.*;
  33 import java.io.*;
  34 
  35 class DnDSource extends Button implements Transferable,
  36         DragGestureListener,
  37         DragSourceListener {
  38     private DataFlavor df;
  39     private transient int dropAction;
  40     private final int dragOperation = DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;
  41     DragSource dragSource = new DragSource();
  42 
  43     DnDSource(String label) {
  44         super(label);
  45         setBackground(Color.yellow);
  46         setForeground(Color.blue);
  47         df = new DataFlavor(DnDSource.class, "DnDSource");
  48 
  49         dragSource.createDefaultDragGestureRecognizer(
  50                 this,
  51                 dragOperation,
  52                 this
  53         );
  54         dragSource.addDragSourceListener(this);
  55     }
  56 
  57     public void changeCursor(
  58             DragSourceContext dsc,
  59             int ra
  60     ) {
  61         java.awt.Cursor c = null;
  62         if ((ra & DnDConstants.ACTION_LINK) == DnDConstants.ACTION_LINK)
  63             c = DragSource.DefaultLinkDrop;
  64         else if ((ra & DnDConstants.ACTION_MOVE) == DnDConstants.ACTION_MOVE)
  65             c = MyCursor.MOVE;//DragSource.DefaultMoveDrop;
  66         else if ((ra & DnDConstants.ACTION_COPY) == DnDConstants.ACTION_COPY)
  67             c = MyCursor.COPY;
  68         else
  69             c = MyCursor.NO_DROP;
  70         dsc.setCursor(c);
  71     }
  72 
  73     /**
  74      * a Drag gesture has been recognized
  75      */
  76 
  77     public void dragGestureRecognized(DragGestureEvent dge) {
  78         System.out.println("starting Drag");
  79         try {
  80             if (DragSource.isDragImageSupported()) {
  81                 System.out.println("starting Imaged Drag");
  82                 dge.startDrag(
  83                         null,
  84                         new ImageGenerator(50, 100, new Color(0xff, 0xff, 0xff, 0x00) ) {
  85                                 @Override public void paint(Graphics gr) {
  86                                     gr.translate(width/2, height/2);
  87                                     ((Graphics2D)gr).setStroke(new BasicStroke(3));
  88                                     int R = width/4+5;
  89                                     gr.setColor(new Color(0x00, 0x00, 0xff, 0x7F));
  90                                     gr.fillRect(-R, -R, 2*R, 2*R);
  91                                     gr.setColor(new Color(0x00, 0x00, 0xff, 0xff));
  92                                     gr.drawRect(-R, -R, 2*R, 2*R);
  93 
  94 
  95                                     gr.translate(10, -10);
  96                                     R -= 5;
  97                                     gr.setColor(Color.RED);
  98                                     gr.fillOval(-R, -R, 2*R, 2*R);
  99                                     gr.setColor(Color.MAGENTA);
 100                                     gr.drawOval(-R, -R, 2*R, 2*R);
 101                                 }
 102                         }.getImage(),
 103                         new Point(15, 40),
 104                         this,
 105                         this);
 106             } else {
 107                 dge.startDrag(
 108                         null,
 109                         this,
 110                         this);
 111             }
 112         } catch (InvalidDnDOperationException e) {
 113             e.printStackTrace();
 114         }
 115     }
 116 
 117     /**
 118      * as the hotspot enters a platform dependent drop site
 119      */
 120 
 121     public void dragEnter(DragSourceDragEvent dsde) {
 122         System.out.println("[Source] dragEnter");
 123         changeCursor(
 124             dsde.getDragSourceContext(),
 125             dsde.getUserAction() & dsde.getDropAction()
 126         );
 127     }
 128 
 129     /**
 130      * as the hotspot moves over a platform dependent drop site
 131      */
 132     public void dragOver(DragSourceDragEvent dsde) {
 133         System.out.println("[Source] dragOver");
 134         changeCursor(
 135             dsde.getDragSourceContext(),
 136             dsde.getUserAction() & dsde.getDropAction()
 137         );
 138         dropAction = dsde.getUserAction() & dsde.getDropAction();
 139         System.out.println("dropAction = " + dropAction);
 140     }
 141 
 142     /**
 143      * as the hotspot exits a platform dependent drop site
 144      */
 145     public void dragExit(DragSourceEvent dse) {
 146         System.out.println("[Source] dragExit");
 147         changeCursor(
 148                 dse.getDragSourceContext(),
 149                 DnDConstants.ACTION_NONE
 150         );
 151     }
 152 
 153     /**
 154      * as the operation changes
 155      */
 156     public void dragGestureChanged(DragSourceDragEvent dsde) {
 157         System.out.println("[Source] dragGestureChanged");
 158         changeCursor(
 159             dsde.getDragSourceContext(),
 160             dsde.getUserAction() & dsde.getDropAction()
 161         );
 162         dropAction = dsde.getUserAction() & dsde.getDropAction();
 163         System.out.println("dropAction = " + dropAction);
 164     }
 165 
 166 
 167     /**
 168      * as the operation completes
 169      */
 170     public void dragDropEnd(DragSourceDropEvent dsde) {
 171         System.out.println("[Source] dragDropEnd");
 172     }
 173 
 174     public void dropActionChanged(DragSourceDragEvent dsde) {
 175         System.out.println("[Source] dropActionChanged");
 176         dropAction = dsde.getUserAction() & dsde.getDropAction();
 177         System.out.println("dropAction = " + dropAction);
 178     }
 179 
 180     public DataFlavor[] getTransferDataFlavors() {
 181         return new DataFlavor[]{df};
 182     }
 183 
 184     public boolean isDataFlavorSupported(DataFlavor sdf) {
 185         return df.equals(sdf);
 186     }
 187 
 188     public Object getTransferData(DataFlavor tdf) throws UnsupportedFlavorException, IOException {
 189         Object copy = null;
 190         if( !df.equals(tdf) ){
 191             throw new UnsupportedFlavorException(tdf);
 192         }
 193         Container parent = getParent();
 194         switch (dropAction) {
 195             case DnDConstants.ACTION_COPY:
 196                 try {
 197                     copy = this.clone();
 198                 } catch (CloneNotSupportedException e) {
 199                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 200                     ObjectOutputStream oos = new ObjectOutputStream(baos);
 201 
 202                     oos.writeObject(this);
 203                     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
 204                     ObjectInputStream ois = new ObjectInputStream(bais);
 205                     try {
 206                         copy = ois.readObject();
 207                     } catch (ClassNotFoundException cnfe) {
 208                         // do nothing
 209                     }
 210                 }
 211                 parent.add(this);
 212                 return copy;
 213 
 214             case DnDConstants.ACTION_MOVE:
 215                 synchronized (this) {
 216                     if (parent != null) {
 217                         parent.remove(this);
 218                         Label label = new Label("[empty]");
 219                         label.setBackground(Color.cyan);
 220                         label.setBounds(this.getBounds());
 221                         parent.add(label);
 222                     }
 223                 }
 224                 return this;
 225 
 226             case DnDConstants.ACTION_LINK:
 227                 return this;
 228 
 229             default:
 230                 return null;
 231         }
 232 
 233     }
 234 }
 235