1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components.util;
21
22 import java.awt.datatransfer.DataFlavor;
23 import java.awt.datatransfer.Transferable;
24 import java.awt.datatransfer.UnsupportedFlavorException;
25 import java.awt.event.MouseEvent;
26 import java.awt.event.MouseMotionListener;
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32
33 import javax.swing.JComponent;
34 import javax.swing.TransferHandler;
35
36
37
38
39
40
41
42
43 public abstract class CosyTransferHandler extends TransferHandler implements MouseMotionListener, Transferable {
44
45 public static final void registerTransferHandler(JComponent parent, TransferHandler newT, JComponent... comps) {
46 TransferHandler oldT= parent.getTransferHandler();
47 if (oldT instanceof CosyTransferHandler) {
48 ((CosyTransferHandler)oldT).unhookTransferHandler(parent);
49 }
50 for (JComponent comp : comps) {
51 if (oldT instanceof CosyTransferHandler) {
52 ((CosyTransferHandler)oldT).unhookTransferHandler(comp);
53 }
54 if (newT instanceof CosyTransferHandler) {
55 ((CosyTransferHandler)newT).hookTransferHandler(comp);
56 }
57 }
58 }
59
60
61
62
63
64
65
66
67
68 public static interface MouseFilter {
69
70
71
72
73
74
75
76 public boolean isDragArea(MouseEvent e);
77 }
78
79 private boolean receiveEnabled=true;
80 private boolean exportEnabled=true;
81 protected boolean isDragging = false;
82 private Set<JComponent> hooked= new HashSet<JComponent>();
83 private List<MouseFilter> filters= new ArrayList<MouseFilter>();
84
85
86
87
88
89
90
91 public CosyTransferHandler(boolean receiveEnabled, boolean exportEnabled) {
92 this.receiveEnabled = receiveEnabled;
93 this.exportEnabled = exportEnabled;
94 }
95
96
97
98
99
100
101
102 public void hookTransferHandler(JComponent comp) {
103 hookTransferHandler(comp,receiveEnabled,exportEnabled);
104 }
105
106
107
108
109
110 public void unhookTransferHandler(JComponent comp) {
111 comp.removeMouseMotionListener(this);
112 hooked.remove(comp);
113 }
114
115
116
117
118
119
120
121
122
123 public void hookTransferHandler(JComponent comp, boolean canReceive, boolean canExport) {
124 if (hooked.contains(comp)) {
125 return;
126 }
127 if (canExport || canReceive) {
128 hooked.add(comp);
129 comp.setTransferHandler(this);
130 }
131 if (canExport) {
132 comp.addMouseMotionListener(this);
133 }
134 }
135
136
137
138
139
140 @Override
141 protected Transferable createTransferable(final JComponent c) {
142 return this;
143 }
144
145
146
147
148
149 public abstract Object getTransferData(DataFlavor flavor)
150 throws UnsupportedFlavorException, IOException;
151
152
153
154
155
156 public boolean isDataFlavorSupported(DataFlavor flavor) {
157 DataFlavor[] flavors= getTransferDataFlavors();
158
159 for (DataFlavor f : flavors) {
160 if (f.equals(flavor)) {
161 return true;
162 }
163 }
164 return false;
165 }
166
167
168
169
170
171 public abstract DataFlavor[] getTransferDataFlavors();
172
173
174
175
176
177 @Override
178 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
179 if (!receiveEnabled) return false;
180 for (DataFlavor flavor : transferFlavors) {
181 if (isDataFlavorSupported(flavor)) {
182 return true;
183 }
184 }
185 return false;
186 }
187
188
189
190
191
192 @Override
193 public int getSourceActions(JComponent c) {
194 return TransferHandler.COPY;
195 }
196
197 protected boolean isMouseDragGesture(MouseEvent e) {
198 return (e.getModifiers()&MouseEvent.BUTTON1)!=MouseEvent.BUTTON1;
199 }
200
201
202
203
204
205 public void mouseDragged(MouseEvent e) {
206 if (!exportEnabled || !isMouseDragGesture(e)) {
207 return;
208 }
209
210 for (MouseFilter f : filters) {
211 if (!f.isDragArea(e)) {
212 return;
213 }
214 }
215
216
217 JComponent c = (JComponent)e.getComponent();
218 if (canDrag(c)) {
219 exportAsDrag(c,e,TransferHandler.COPY);
220 isDragging = true;
221 }
222 }
223
224
225
226
227
228 @Override
229 protected void exportDone(JComponent source, Transferable data, int action) {
230 super.exportDone(source, data, action);
231 isDragging = false;
232 }
233
234
235
236
237
238
239
240 protected boolean canDrag(JComponent comp) {
241 return exportEnabled;
242 }
243
244
245
246
247
248 public void mouseMoved(MouseEvent e) {
249
250 }
251
252
253
254
255
256
257
258 public boolean isExportEnabled() {
259 return exportEnabled;
260 }
261
262
263
264
265
266
267
268 public boolean isReceiveEnabled() {
269 return receiveEnabled;
270 }
271
272
273
274
275
276
277
278
279 public void setExportEnabled(boolean exportEnabled, JComponent comp) {
280 if (this.exportEnabled != exportEnabled) {
281 this.exportEnabled = exportEnabled;
282 unhookTransferHandler(comp);
283 hookTransferHandler(comp);
284 }
285 }
286
287
288
289
290
291
292
293
294 public void setReceiveEnabled(boolean receiveEnabled, JComponent comp) {
295 if (this.receiveEnabled != receiveEnabled) {
296 this.receiveEnabled = receiveEnabled;
297 unhookTransferHandler(comp);
298 hookTransferHandler(comp);
299 }
300 }
301
302
303
304
305
306
307 public void addMouseFilter(MouseFilter f) {
308 filters.add(f);
309 }
310
311
312
313
314
315
316 public void removeMouseFilter(MouseFilter f) {
317 filters.remove(f);
318 }
319
320
321
322
323
324
325 public MouseFilter[] getMouseFilters() {
326 return filters.toArray(new MouseFilter[filters.size()]);
327 }
328
329 }
330
331
332