1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.mlc.swing.layout;
31
32 import java.awt.*;
33 import java.awt.datatransfer.DataFlavor;
34 import java.awt.datatransfer.Transferable;
35 import java.awt.dnd.*;
36
37
38 import javax.swing.*;
39
40
41 import com.jgoodies.forms.layout.CellConstraints;
42
43 /***
44 * I'm creating a table subclass to make it easier to handle dragging and
45 * dropping
46 * http://www.hut.fi/~landerso/cccp/src/java/cccp/mappingtool/util/MTTable.java
47 */
48 @SuppressWarnings("serial")
49 class DnDTable extends JTable implements DragSourceListener,
50 DragGestureListener, DropTargetListener, Autoscroll
51 {
52 protected DragSource fDragSource = null;
53 protected DropTarget fDropTarget = null;
54 protected Component dragComponent = null;
55
56 final static int AUTOSCROLL_INSET_SIZE = 20;
57 final static int SCROLL_AMOUNT = 10;
58
59 FormEditor parent;
60 LayoutFrame superparent;
61
62 public DnDTable(LayoutFrame granddaddy, FormEditor daddy)
63 {
64 super();
65
66 parent = daddy;
67 superparent = granddaddy;
68
69 fDragSource = new DragSource();
70 fDropTarget = new DropTarget(this, this);
71 fDragSource.createDefaultDragGestureRecognizer(this,
72 DnDConstants.ACTION_MOVE, this);
73 }
74
75 /***
76 * Drag and drop is kind of weird in that when you drag something, you often
77 * start in a cell that has a component in it but by the time the drag
78 * handling code get's the event the selection has moved into a cell that
79 * does have a component in it and the drag fails.
80 */
81 public void changeSelection(int rowIndex, int columnIndex, boolean toggle,
82 boolean extend)
83 {
84 super.changeSelection(rowIndex, columnIndex, toggle, extend);
85
86 Component component = getSelectedControl();
87 parent.setFormComponent(component);
88
89 if (component != null)
90 {
91
92
93
94 parent.componentList.setSelectedValue(component, true);
95 }
96 else
97 {
98 ;
99 }
100 }
101
102 /***
103 * Implements autoscrolling.
104 */
105 public Insets getAutoscrollInsets()
106 {
107 Rectangle visible = getVisibleRect();
108 Dimension size = getSize();
109 int top = 0, left = 0, bottom = 0, right = 0;
110 if (visible.y > 0)
111 top = visible.y + AUTOSCROLL_INSET_SIZE;
112 if (visible.x > 0)
113 left = visible.x + AUTOSCROLL_INSET_SIZE;
114 if (visible.y + visible.height < size.height)
115 bottom = size.height - visible.y - visible.height + AUTOSCROLL_INSET_SIZE;
116 if (visible.x + visible.width < size.width)
117 right = size.width - visible.x - visible.width + AUTOSCROLL_INSET_SIZE;
118 return new Insets(top, left, bottom, right);
119 }
120
121 /***
122 * Implements autoscrolling.
123 */
124 public void autoscroll(Point cursorLocn)
125 {
126 Rectangle visible = getVisibleRect();
127 int x = 0, y = 0, width = 0, height = 0;
128
129 if (cursorLocn.x < visible.x + AUTOSCROLL_INSET_SIZE)
130 {
131 x = -SCROLL_AMOUNT;
132 width = SCROLL_AMOUNT;
133 }
134
135 else if (cursorLocn.x > visible.x + visible.width - AUTOSCROLL_INSET_SIZE)
136 {
137 x = visible.width + SCROLL_AMOUNT;
138 width = SCROLL_AMOUNT;
139 }
140
141 if (cursorLocn.y < visible.y + AUTOSCROLL_INSET_SIZE)
142 {
143 y = -SCROLL_AMOUNT;
144 height = SCROLL_AMOUNT;
145 }
146
147 else if (cursorLocn.y > visible.y + visible.height - AUTOSCROLL_INSET_SIZE)
148 {
149 y = visible.height + SCROLL_AMOUNT;
150 height = SCROLL_AMOUNT;
151 }
152 ((JComponent) getParent()).scrollRectToVisible(new Rectangle(x, y, width, height));
153 }
154
155 public void dragEnter(DragSourceDragEvent event) {}
156 public void dragOver(DragSourceDragEvent event)
157 {
158 DragSourceContext context = event.getDragSourceContext();
159 java.awt.Point location = event.getLocation();
160 Point org = this.getLocationOnScreen();
161 Point relLoc = new Point( location.x - org.x,
162 location.y - org.y );
163
164 int col = columnAtPoint(relLoc);
165 int row = rowAtPoint(relLoc);
166 Component component = getControlAt(col,row);
167
168 if ( col < 1 || row < 1 || component != null )
169 context.setCursor(DragSource.DefaultMoveNoDrop);
170 else
171 context.setCursor(DragSource.DefaultMoveDrop);
172 }
173 public void dropActionChanged(DragSourceDragEvent event) {}
174 public void dragExit(DragSourceEvent event) {}
175 public void dragDropEnd(DragSourceDropEvent event) {}
176 public void dropActionChanged(DropTargetDragEvent event) {}
177 public void dragExit(DropTargetEvent event) {}
178
179 public void dragGestureRecognized(DragGestureEvent event)
180 {
181 Point p = event.getDragOrigin();
182 int row = rowAtPoint(p);
183 int col = columnAtPoint(p);
184 Component component = getControlAt(col,row);
185 if (component != null)
186 {
187 event.startDrag(java.awt.dnd.DragSource.DefaultMoveDrop,
188 new TransferableWrapper(component), this);
189 }
190 }
191
192 public void dragEnter(DropTargetDragEvent dropTargetDragEvent)
193 {
194 try
195 {
196 if (dropTargetDragEvent.isDataFlavorSupported(new DataFlavor(
197 DataFlavor.javaJVMLocalObjectMimeType)))
198 dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_MOVE);
199 else
200 dropTargetDragEvent.rejectDrag();
201 }
202 catch (ClassNotFoundException cnfe)
203 {
204 cnfe.printStackTrace();
205 }
206 }
207
208 public void dragOver(java.awt.dnd.DropTargetDragEvent dropTargetDragEvent)
209 {
210 DropTargetContext context = dropTargetDragEvent.getDropTargetContext();
211
212 try
213 {
214 java.awt.Point location = dropTargetDragEvent.getLocation();
215 int col = columnAtPoint(location);
216 int row = rowAtPoint(location);
217
218 if (dropTargetDragEvent.isDataFlavorSupported(new DataFlavor(
219 DataFlavor.javaJVMLocalObjectMimeType)))
220 dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_MOVE);
221 else
222 {
223 dropTargetDragEvent.rejectDrag();
224 }
225 }
226 catch (ClassNotFoundException cnfe)
227 {
228 cnfe.printStackTrace();
229 }
230 }
231
232 public void drop(java.awt.dnd.DropTargetDropEvent e)
233 {
234 CellConstraints componentConstraints = null;
235 Component component = null;
236
237 try
238 {
239
240 java.awt.Point location = e.getLocation();
241 int col = columnAtPoint(location);
242 int row = rowAtPoint(location);
243 Component existComp = getControlAt(col,row);
244
245 if ( col < 1 || row < 1 || existComp != null )
246 {
247
248 e.rejectDrop();
249 e.getDropTargetContext().dropComplete(true);
250 return;
251 }
252
253 DataFlavor javaObject = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType);
254 if ( !e.isDataFlavorSupported(javaObject) )
255 {
256
257 e.rejectDrop();
258 return;
259 }
260
261 {
262 e.acceptDrop(DnDConstants.ACTION_MOVE);
263 Transferable transferable = e.getTransferable();
264 Object dropObject = transferable.getTransferData(javaObject);
265
266 if (dropObject instanceof ComponentDef)
267 {
268 ComponentDef componentDef = (ComponentDef) dropObject;
269
270 NewComponentDialog dlg = NewComponentDialog.doDialog(superparent, componentDef);
271 if (dlg.succeeded())
272 {
273 String componentName = dlg.getComponentName();
274 componentDef = dlg.componentDef;
275
276
277 int suffix = 1;
278 while (parent.containerLayout.getComponentByName(componentName) != null)
279 {
280 componentName = dlg.getComponentName() + "_" + suffix;
281 suffix++;
282 }
283 componentDef.name = componentName;
284
285 component = null;
286 try
287 {
288 component = dlg.getInstance();
289 componentConstraints = new CellConstraints(col, row);
290
291
292
293
294 boolean isContainer = componentDef.isContainer;
295
296
297
298
299
300
301 parent.containerLayout.addComponent(componentName, componentDef, componentConstraints);
302 parent.container.add(component, componentName);
303 parent.newComponents.add(component);
304
305 if (isContainer)
306 superparent.addContainer(componentName, (Container) component);
307
308 e.dropComplete(true);
309 parent.updateList();
310
311 parent.updateLayout(component);
312 parent.updateLayouts();
313 changeSelection(componentConstraints.gridY,componentConstraints.gridX, false, false);
314 repaint();
315 return;
316
317 }
318 catch (Throwable t)
319 {
320 t.printStackTrace();
321
322
323
324
325
326 e.dropComplete(false);
327 return;
328 }
329 }
330 }
331
332 else if (dropObject instanceof Component)
333 {
334 component = (Component) dropObject;
335 componentConstraints = parent.getComponentConstraints(component);
336
337 if (col > 0 && row > 0)
338 {
339 componentConstraints.gridX = col;
340 componentConstraints.gridY = row;
341 componentConstraints.gridWidth = Math.min(
342 componentConstraints.gridWidth, parent.containerLayout
343 .getColumnCount()
344 - componentConstraints.gridX + 1);
345 componentConstraints.gridHeight = Math.min(
346 componentConstraints.gridHeight, parent.containerLayout
347 .getRowCount()
348 - componentConstraints.gridY + 1);
349
350 if (!component.isVisible())
351 component.setVisible(true);
352 parent.topComponent = component;
353
354 e.dropComplete(true);
355
356
357
358
359 parent.updateLayout(component);
360 changeSelection(componentConstraints.gridY,componentConstraints.gridX, false, false);
361
362
363
364 repaint();
365
366
367 parent.updateList();
368
369 return;
370 }
371 }
372 else
373 {
374
375 e.dropComplete(false);
376 return;
377 }
378 }
379 }
380 catch (Exception exception)
381 {
382 exception.printStackTrace();
383
384 e.rejectDrop();
385 return;
386 }
387 }
388
389 public Component getControlAt(int col, int row)
390 {
391 Component component = (row == 0 || col == 0) ? null
392 : (Component) getModel().getValueAt(row, col);
393 return component;
394 }
395 public Component getSelectedControl()
396 {
397 int col = getSelectedColumn();
398 int row = getSelectedRow();
399 return getControlAt(col,row);
400 }
401 }