DnDSource.java revision 8729:0242fce0f717
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
28import java.awt.*;
29import java.awt.datatransfer.*;
30
31import java.awt.image.ImageConsumer;
32import java.awt.image.MemoryImageSource;
33
34import java.awt.dnd.*;
35import java.io.*;
36
37class 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
272