1 package org.apache.log4j.chainsaw.dnd;
2
3
4 import org.apache.log4j.Logger;
5 import java.awt.datatransfer.DataFlavor;
6 import java.awt.Color;
7 import java.awt.datatransfer.Transferable;
8 import java.awt.dnd.DnDConstants;
9 import java.awt.dnd.DropTarget;
10 import java.awt.dnd.DropTargetDragEvent;
11 import java.awt.dnd.DropTargetDropEvent;
12 import java.awt.dnd.DropTargetEvent;
13 import java.awt.dnd.DropTargetListener;
14 import java.beans.PropertyChangeListener;
15 import java.beans.PropertyChangeSupport;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import javax.swing.BorderFactory;
21 import javax.swing.JComponent;
22
23 /***
24 * This class provides all the functionality to work out when files are dragged onto
25 * a particular JComponent instance, and then notifies listeners via
26 * the standard PropertyChangesListener semantics to indicate that a list of
27 * files have been dropped onto the target.
28 *
29 * If you wish to know whan the files have been dropped, subscribe to the "fileList" property change.
30 *
31 * @author psmith
32 *
33 */
34 public class FileDnDTarget implements DropTargetListener{
35 /***
36 * Logger for this class
37 */
38 private static final Logger LOG = Logger.getLogger(FileDnDTarget.class);
39
40 protected int acceptableActions = DnDConstants.ACTION_COPY;
41
42 private DropTarget dropTarget;
43 private List fileList;
44
45 private JComponent guiTarget;
46 private Map dropTargets = new HashMap();
47
48
49 private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
50 /***
51 *
52 */
53 public FileDnDTarget(JComponent c) {
54 this.guiTarget = c;
55 dropTarget = new DropTarget(this.guiTarget, this);
56 }
57
58 public void addDropTargetToComponent(JComponent c){
59 dropTargets.put(c, new DropTarget(c, this));
60 }
61
62 /***
63 * @param listener
64 */
65 public void addPropertyChangeListener(PropertyChangeListener listener) {
66 propertySupport.addPropertyChangeListener(listener);
67 }
68 /***
69 * @param propertyName
70 * @param listener
71 */
72 public void addPropertyChangeListener(String propertyName,
73 PropertyChangeListener listener) {
74 propertySupport.addPropertyChangeListener(propertyName, listener);
75 }
76
77 /***
78 *
79 */
80 private void decorateComponent() {
81
82 guiTarget.setBorder(BorderFactory.createLineBorder(Color.black));
83 }
84
85
86 public void dragEnter(DropTargetDragEvent e) {
87
88 if (isDragOk(e) == false) {
89 e.rejectDrag();
90 return;
91 }
92 decorateComponent();
93
94 e.acceptDrag(acceptableActions);
95 }
96
97
98 public void dragExit(DropTargetEvent dte) {
99 removeComponentDecoration();
100 }
101
102
103 public void dragOver(DropTargetDragEvent e) {
104
105
106 if (isDragOk(e) == false) {
107 e.rejectDrag();
108 return;
109 }
110 e.acceptDrag(acceptableActions);
111 }
112
113 public void drop(DropTargetDropEvent dtde) {
114 Transferable transferable = dtde.getTransferable();
115 LOG.debug(transferable);
116 dtde.acceptDrop(acceptableActions);
117 try {
118 List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor);
119 LOG.debug(list);
120 setFileList(list);
121 dtde.getDropTargetContext().dropComplete(true);
122 removeComponentDecoration();
123
124 } catch (Exception e) {
125 LOG.error("Error with DnD", e);
126 }
127
128 }
129
130 public void dropActionChanged(DropTargetDragEvent dtde) {
131
132 }
133 /***
134 * @return Returns the fileList.
135 */
136 public final List getFileList() {
137 return fileList;
138 }
139
140 private boolean isDragOk(DropTargetDragEvent e) {
141 DataFlavor[] flavors = new DataFlavor[] { DataFlavor.javaFileListFlavor };
142 DataFlavor chosen = null;
143 for (int i = 0; i < flavors.length; i++) {
144 if (e.isDataFlavorSupported(flavors[i])) {
145 chosen = flavors[i];
146 break;
147 }
148 }
149
150
151
152 if (chosen == null) {
153 return false;
154 }
155
156
157 int sa = e.getSourceActions();
158
159
160 if ((sa & acceptableActions) == 0)
161 return false;
162 return true;
163 }
164
165 /***
166 *
167 */
168 private void removeComponentDecoration() {
169 this.guiTarget.setBorder(null);
170 }
171 /***
172 * @param listener
173 */
174 public void removePropertyChangeListener(PropertyChangeListener listener) {
175 propertySupport.removePropertyChangeListener(listener);
176 }
177 /***
178 * @param propertyName
179 * @param listener
180 */
181 public void removePropertyChangeListener(String propertyName,
182 PropertyChangeListener listener) {
183 propertySupport.removePropertyChangeListener(propertyName, listener);
184 }
185
186 /***
187 * @param fileList The fileList to set.
188 */
189 private final void setFileList(List fileList) {
190 Object oldValue = this.fileList;
191 this.fileList = fileList;
192 propertySupport.firePropertyChange("fileList", oldValue, this.fileList);
193 }
194 }