KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > gui > FileDrop


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2002 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19

20 package com.puppycrawl.tools.checkstyle.gui;
21
22 import java.awt.Color JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Container JavaDoc;
25 import java.awt.datatransfer.DataFlavor JavaDoc;
26 import java.awt.datatransfer.Transferable JavaDoc;
27 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
28 import java.awt.dnd.DnDConstants JavaDoc;
29 import java.awt.dnd.DropTarget JavaDoc;
30 import java.awt.dnd.DropTargetDragEvent JavaDoc;
31 import java.awt.dnd.DropTargetDropEvent JavaDoc;
32 import java.awt.dnd.DropTargetEvent JavaDoc;
33 import java.awt.dnd.DropTargetListener JavaDoc;
34 import java.awt.event.HierarchyEvent JavaDoc;
35 import java.awt.event.HierarchyListener JavaDoc;
36 import java.io.File JavaDoc;
37 import java.io.IOException JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.TooManyListenersException JavaDoc;
40 import javax.swing.BorderFactory JavaDoc;
41 import javax.swing.JComponent JavaDoc;
42 import javax.swing.border.Border JavaDoc;
43
44 /**
45  * This class makes it easy to drag and drop files from the operating
46  * system to a Java program. Any <tt>java.awt.Component</tt> can be
47  * dropped onto, but only <tt>javax.swing.JComponent</tt>s will indicate
48  * the drop event with a changed border.
49  * <p/>
50  * To use this class, construct a new <tt>FileDrop</tt> by passing
51  * it the target component and a <tt>Listener</tt> to receive notification
52  * when file(s) have been dropped. Here is an example:
53  * <p/>
54  * <code><pre>
55  * JPanel myPanel = new JPanel();
56  * new FileDrop( myPanel, new FileDrop.Listener()
57  * { public void filesDropped( java.io.File[] files )
58  * {
59  * // handle file drop
60  * ...
61  * } // end filesDropped
62  * }); // end FileDrop.Listener
63  * </pre></code>
64  * <p/>
65  * You can specify the border that will appear when files are being dragged by
66  * calling the constructor with a <tt>javax.swing.border.Border</tt>. Only
67  * <tt>JComponent</tt>s will show any indication with a border.
68  * <p/>
69  *
70  * <p>Original author: Robert Harder, rharder@usa.net</p>
71  *
72  * @author Robert Harder
73  * @author Lars K?hne
74  */

75 class FileDrop
76 {
77     // TODO: Not sure that changing borders is a good idea.
78
// At least we should make sure that the border insets are preserved so
79
// that the panel layout does not change during the DnD operation.
80

81     private transient Border JavaDoc normalBorder;
82     private transient DropTargetListener JavaDoc dropListener;
83
84     // TODO: Blue is not a nice color in all LookAndFeels
85
/* Default border color */
86     private static final Color JavaDoc DEFAULT_BORDER_COLOR =
87             new Color JavaDoc(0f, 0f, 1f, 0.25f);
88
89     /**
90      * Constructs a {@link FileDrop} with a default light-blue border
91      * and, if <var>c</var> is a {@link java.awt.Container}, recursively
92      * sets all elements contained within as drop targets, though only
93      * the top level container will change borders.
94      *
95      * @param c Component on which files will be dropped.
96      * @param listener Listens for <tt>filesDropped</tt>.
97      * @since 1.0
98      */

99     FileDrop(
100             final Component JavaDoc c,
101             final Listener JavaDoc listener)
102             throws TooManyListenersException JavaDoc
103     {
104         this( c, // Drop target
105
BorderFactory.createMatteBorder(2, 2, 2, 2, DEFAULT_BORDER_COLOR), // Drag border
106
true, // Recursive
107
listener);
108     }
109
110
111     /**
112      * Full constructor with a specified border and debugging optionally turned on.
113      * With Debugging turned on, more status messages will be displayed to
114      * <tt>out</tt>. A common way to use this constructor is with
115      * <tt>System.out</tt> or <tt>System.err</tt>. A <tt>null</tt> value for
116      * the parameter <tt>out</tt> will result in no debugging output.
117      *
118      * @param c Component on which files will be dropped.
119      * @param dragBorder Border to use on <tt>JComponent</tt> when dragging occurs.
120      * @param recursive Recursively set children as drop targets.
121      * @param listener Listens for <tt>filesDropped</tt>.
122      * @since 1.0
123      */

124     FileDrop(
125             final Component JavaDoc c,
126             final Border JavaDoc dragBorder,
127             final boolean recursive,
128             final Listener JavaDoc listener)
129             throws TooManyListenersException JavaDoc
130     {
131         dropListener = new FileDropTargetListener(c, dragBorder, listener);
132         makeDropTarget(c, recursive);
133     }
134
135
136     private void makeDropTarget(final Component JavaDoc c, boolean recursive)
137             throws TooManyListenersException JavaDoc
138     {
139         // Make drop target
140
final DropTarget JavaDoc dt = new DropTarget JavaDoc();
141         dt.addDropTargetListener(dropListener);
142
143         // Listen for hierarchy changes and remove the
144
// drop target when the parent gets cleared out.
145
c.addHierarchyListener(new HierarchyListener JavaDoc()
146         {
147             public void hierarchyChanged(HierarchyEvent JavaDoc evt)
148             {
149                 final Component JavaDoc parent = c.getParent();
150                 if (parent == null) {
151                     c.setDropTarget(null);
152                 }
153                 else {
154                     new DropTarget JavaDoc(c, dropListener);
155                 }
156             }
157         });
158
159         if (c.getParent() != null) {
160             new DropTarget JavaDoc(c, dropListener);
161         }
162
163         if (recursive && (c instanceof Container JavaDoc)) {
164             final Container JavaDoc cont = (Container JavaDoc) c;
165             final Component JavaDoc[] comps = cont.getComponents();
166             for (int i = 0; i < comps.length; i++)
167                 makeDropTarget(comps[i], recursive);
168         }
169     }
170
171
172     /** Determine if the dragged data is a file list. */
173     private boolean isDragOk(final DropTargetDragEvent JavaDoc evt)
174     {
175         boolean ok = false;
176         final DataFlavor JavaDoc[] flavors = evt.getCurrentDataFlavors();
177
178         // See if any of the flavors are a file list
179
int i = 0;
180         while (!ok && (i < flavors.length)) { // Is the flavor a file list?
181
if (flavors[i].equals(DataFlavor.javaFileListFlavor))
182                 ok = true;
183             i++;
184         }
185
186         return ok;
187     }
188
189
190     /**
191      * Removes the drag-and-drop hooks from the component and optionally
192      * from the all children. You should call this if you add and remove
193      * components after you've set up the drag-and-drop.
194      * This will recursively unregister all components contained within
195      * <var>c</var> if <var>c</var> is a {@link Container}.
196      *
197      * @param c The component to unregister as a drop target
198      * @since 1.0
199      */

200     static void remove(Component JavaDoc c)
201     {
202         remove(c, true);
203     }
204
205
206     /**
207      * Removes the drag-and-drop hooks from the component and optionally
208      * from the all children. You should call this if you add and remove
209      * components after you've set up the drag-and-drop.
210      *
211      * @param c The component to unregister
212      * @param recursive Recursively unregister components within a container
213      * @since 1.0
214      */

215     static void remove(Component JavaDoc c, boolean recursive)
216     {
217         c.setDropTarget(null);
218         if (recursive && (c instanceof Container JavaDoc)) {
219             final Component JavaDoc[] comps = ((Container JavaDoc) c).getComponents();
220             for (int i = 0; i < comps.length; i++) {
221                 remove(comps[i], recursive);
222             }
223         }
224     }
225
226
227     /**
228      * Implement this inner interface to listen for when files are dropped. For example
229      * your class declaration may begin like this:
230      * <code><pre>
231      * public class MyClass implements FileDrop.Listener
232      * ...
233      * public void filesDropped( File[] files )
234      * {
235      * ...
236      * } // end filesDropped
237      * ...
238      * </pre></code>
239      *
240      * @since 1.0
241      */

242     public interface Listener
243     {
244         /**
245          * This method is called when files have been successfully dropped.
246          *
247          * @param files An array of <tt>File</tt>s that were dropped.
248          * @since 1.0
249          */

250         void filesDropped(File JavaDoc[] files);
251     }
252
253     private class FileDropTargetListener implements DropTargetListener JavaDoc
254     {
255         private final Component JavaDoc mC;
256         private final Border JavaDoc mDragBorder;
257         private final Listener JavaDoc mListener;
258
259         public void dragEnter(DropTargetDragEvent JavaDoc evt)
260         {
261             if (isDragOk(evt)) {
262                 if (mC instanceof JComponent JavaDoc) {
263                     final JComponent JavaDoc jc = (JComponent JavaDoc) mC;
264                     normalBorder = jc.getBorder();
265                     jc.setBorder(mDragBorder);
266                 }
267                 evt.acceptDrag(DnDConstants.ACTION_COPY);
268             }
269             else {
270                 evt.rejectDrag();
271             }
272         }
273
274         public void drop(DropTargetDropEvent JavaDoc evt)
275         {
276             try {
277                 final Transferable JavaDoc tr = evt.getTransferable();
278
279                 if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
280                     evt.acceptDrop(DnDConstants.ACTION_COPY);
281
282                     final List JavaDoc fileList = (List JavaDoc) tr.getTransferData(
283                             DataFlavor.javaFileListFlavor);
284                     final File JavaDoc[] files = new File JavaDoc[fileList.size()];
285                     fileList.toArray(files);
286
287                     if (mListener != null) {
288                         mListener.filesDropped(files);
289                     }
290
291                     evt.getDropTargetContext().dropComplete(true);
292                 }
293                 else {
294                     evt.rejectDrop();
295                 }
296             }
297             catch (final IOException JavaDoc io) {
298                 evt.rejectDrop();
299             }
300             catch (final UnsupportedFlavorException JavaDoc ufe) {
301                 evt.rejectDrop();
302             }
303             finally {
304                 if (mC instanceof JComponent JavaDoc) {
305                     final JComponent JavaDoc jc = (JComponent JavaDoc) mC;
306                     jc.setBorder(normalBorder);
307                 }
308             }
309         }
310
311         public void dragExit(DropTargetEvent JavaDoc evt)
312         {
313             if (mC instanceof JComponent JavaDoc) {
314                 final JComponent JavaDoc jc = (JComponent JavaDoc) mC;
315                 jc.setBorder(normalBorder);
316             }
317         }
318
319         public void dropActionChanged(DropTargetDragEvent JavaDoc evt)
320         {
321             if (isDragOk(evt)) {
322                 evt.acceptDrag(DnDConstants.ACTION_COPY);
323             }
324             else {
325                 evt.rejectDrag();
326             }
327         }
328
329         public void dragOver(DropTargetDragEvent JavaDoc dtde)
330         {
331         }
332
333         public FileDropTargetListener(Component JavaDoc aC, Border JavaDoc aDragBorder, Listener JavaDoc aListener)
334         {
335             mC = aC;
336             mDragBorder = aDragBorder;
337             mListener = aListener;
338         }
339     }
340
341 }
Popular Tags