1 /*
2  * Copyright (c) 2009, 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.
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 
DnDSource(String label)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 
changeCursor( DragSourceContext dsc, int ra )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 
dragGestureRecognized(DragGestureEvent dge)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(Color.BLUE);
88                                     gr.fillRect(-R, -R, 2*R, 2*R);
89                                     gr.setColor(Color.CYAN);
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 
dragEnter(DragSourceDragEvent dsde)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      */
dragOver(DragSourceDragEvent dsde)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      */
dragExit(DragSourceEvent dse)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      */
dragGestureChanged(DragSourceDragEvent dsde)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      */
dragDropEnd(DragSourceDropEvent dsde)168     public void dragDropEnd(DragSourceDropEvent dsde) {
169         System.out.println("[Source] dragDropEnd");
170     }
171 
dropActionChanged(DragSourceDragEvent dsde)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 
getTransferDataFlavors()178     public DataFlavor[] getTransferDataFlavors() {
179         return new DataFlavor[]{df};
180     }
181 
isDataFlavorSupported(DataFlavor sdf)182     public boolean isDataFlavorSupported(DataFlavor sdf) {
183         return df.equals(sdf);
184     }
185 
getTransferData(DataFlavor tdf)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 
234