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