Revision 10656 branches/v10/applications/appgvSIG/src/com/iver/cit/gvsig/project/documents/view/toc/DnDJTree.java
DnDJTree.java | ||
---|---|---|
44 | 44 |
*/ |
45 | 45 |
package com.iver.cit.gvsig.project.documents.view.toc; |
46 | 46 |
/* |
47 |
** This is version II of DnDJTree. The first version allowed for what I
|
|
47 |
** This is version II of DnDJTree. The first version allowed for what I |
|
48 | 48 |
** thought was a JDK oversight. However, we can set the cursor appropriately, |
49 | 49 |
** relative to whether the current cursor location is a valid drop target. |
50 | 50 |
** |
51 | 51 |
** If this is your first time reading the source code. Just ignore the above |
52 |
** comment and ignore the "CHANGED" comments below. Otherwise, the
|
|
52 |
** comment and ignore the "CHANGED" comments below. Otherwise, the |
|
53 | 53 |
** "CHANGED" comments will show where the code has changed. |
54 | 54 |
** |
55 | 55 |
** Credit for finding this shortcoming in my code goes Laurent Hubert. |
... | ... | |
97 | 97 |
import com.iver.cit.gvsig.project.documents.view.gui.View; |
98 | 98 |
|
99 | 99 |
public class DnDJTree extends JTree |
100 |
implements TreeSelectionListener,
|
|
100 |
implements TreeSelectionListener, |
|
101 | 101 |
DragGestureListener, DropTargetListener, |
102 | 102 |
DragSourceListener { |
103 | 103 |
|
104 | 104 |
protected ArrayList m_Listeners = new ArrayList(); |
105 |
|
|
105 |
|
|
106 | 106 |
private static DnDJTree oDnDtocOrigin = null; |
107 | 107 |
private static DnDJTree oDnDtocDestination = null; |
108 | 108 |
/** Stores the parent Frame of the component */ |
... | ... | |
119 | 119 |
//private ArrayList treeListeners=new ArrayList(); |
120 | 120 |
//private ArrayList dropListeners=new ArrayList(); |
121 | 121 |
// private TreeModel model1; |
122 |
/** Constructor
|
|
122 |
/** Constructor |
|
123 | 123 |
@param root The root node of the tree |
124 | 124 |
@param parent Parent JFrame of the JTree */ |
125 | 125 |
public DnDJTree(TreeModel treeModel) { |
... | ... | |
131 | 131 |
/* ********************** CHANGED ********************** */ |
132 | 132 |
dragSource = DragSource.getDefaultDragSource() ; |
133 | 133 |
/* ****************** END OF CHANGE ******************** */ |
134 |
|
|
135 |
DragGestureRecognizer dgr =
|
|
134 |
|
|
135 |
DragGestureRecognizer dgr = |
|
136 | 136 |
dragSource.createDefaultDragGestureRecognizer( |
137 | 137 |
this, //DragSource |
138 | 138 |
DnDConstants.ACTION_COPY_OR_MOVE, //specifies valid actions |
... | ... | |
146 | 146 |
dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK); |
147 | 147 |
|
148 | 148 |
/* First argument: Component to associate the target with |
149 |
* Second argument: DropTargetListener
|
|
149 |
* Second argument: DropTargetListener |
|
150 | 150 |
*/ |
151 | 151 |
//DropTarget dropTarget = new DropTarget(this, this); |
152 | 152 |
setDropTarget(); |
... | ... | |
156 | 156 |
removeTreeListener(); |
157 | 157 |
} |
158 | 158 |
private void addDropListener(){ |
159 |
dropTarget= new DropTarget(this, this);
|
|
159 |
dropTarget= new DropTarget(this, this); |
|
160 | 160 |
} |
161 | 161 |
private void removeDropListener(){ |
162 | 162 |
dropTarget=null; |
... | ... | |
197 | 197 |
DefaultMutableTreeNode dragNode = getSelectedNode(); |
198 | 198 |
if (dragNode != null) { |
199 | 199 |
|
200 |
|
|
200 |
|
|
201 | 201 |
if (!(dragNode.getUserObject() instanceof Transferable)) return; |
202 |
|
|
202 |
|
|
203 | 203 |
// Get the Transferable Object |
204 | 204 |
Transferable transferable = (Transferable) dragNode.getUserObject(); |
205 |
|
|
205 |
|
|
206 | 206 |
/* ********************** CHANGED ********************** */ |
207 | 207 |
|
208 | 208 |
//Select the appropriate cursor; |
209 | 209 |
// Cursor cursor = DragSource.DefaultCopyNoDrop; |
210 | 210 |
int action = e.getDragAction(); |
211 |
/* if (action == DnDConstants.ACTION_MOVE)
|
|
211 |
/* if (action == DnDConstants.ACTION_MOVE) |
|
212 | 212 |
cursor = DragSource.DefaultMoveDrop; */ |
213 |
|
|
214 |
|
|
213 |
|
|
214 |
|
|
215 | 215 |
//In fact the cursor is set to NoDrop because once an action is rejected |
216 | 216 |
// by a dropTarget, the dragSourceListener are no more invoked. |
217 |
// Setting the cursor to no drop by default is so more logical, because
|
|
217 |
// Setting the cursor to no drop by default is so more logical, because |
|
218 | 218 |
// when the drop is accepted by a component, then the cursor is changed by the |
219 | 219 |
// dropActionChanged of the default DragSource. |
220 | 220 |
/* ****************** END OF CHANGE ******************** */ |
221 |
|
|
221 |
|
|
222 | 222 |
//begin the drag |
223 | 223 |
oDnDtocOrigin = this; |
224 | 224 |
dragSource.startDrag(e, null, transferable, this); |
... | ... | |
233 | 233 |
public void dragEnter(DragSourceDragEvent dsde) { |
234 | 234 |
/* ********************** CHANGED ********************** */ |
235 | 235 |
// System.err.println("dragOver" + dsde.getDragSourceContext().getComponent()); |
236 |
|
|
236 |
|
|
237 | 237 |
/* ****************** END OF CHANGE ******************** */ |
238 | 238 |
} |
239 | 239 |
|
... | ... | |
251 | 251 |
/** DragSourceListener interface method */ |
252 | 252 |
public void dragExit(DragSourceEvent dsde) { |
253 | 253 |
} |
254 |
|
|
254 |
|
|
255 | 255 |
/** DropTargetListener interface method - What we do when drag is released */ |
256 | 256 |
public void drop(DropTargetDropEvent e) { |
257 | 257 |
try { |
... | ... | |
259 | 259 |
//flavor not supported, reject drop |
260 | 260 |
if (!tr.isDataFlavorSupported( TocItemBranch.INFO_FLAVOR)) e.rejectDrop(); |
261 | 261 |
//cast into appropriate data type |
262 |
TocItemBranch childInfo =
|
|
263 |
(TocItemBranch) tr.getTransferData( TocItemBranch.INFO_FLAVOR );
|
|
262 |
TocItemBranch childInfo = |
|
263 |
(TocItemBranch) tr.getTransferData( TocItemBranch.INFO_FLAVOR ); |
|
264 | 264 |
//get new parent node |
265 | 265 |
Point loc = e.getLocation(); |
266 | 266 |
TreePath destinationPath = getPathForLocation(loc.x, loc.y); |
... | ... | |
274 | 274 |
public void run() { |
275 | 275 |
System.err.println(msg); |
276 | 276 |
} |
277 |
});
|
|
277 |
}); |
|
278 | 278 |
return; |
279 | 279 |
/* } |
280 | 280 |
else |
... | ... | |
298 | 298 |
//boolean isContainer=false; |
299 | 299 |
|
300 | 300 |
DefaultMutableTreeNode nodoTocado = |
301 |
(DefaultMutableTreeNode) destinationPath.getLastPathComponent();
|
|
301 |
(DefaultMutableTreeNode) destinationPath.getLastPathComponent(); |
|
302 | 302 |
// get old parent node |
303 | 303 |
DefaultMutableTreeNode oldParent = (DefaultMutableTreeNode) getSelectedNode().getParent(); |
304 | 304 |
if (nodoTocado.getParent().equals(getSelectedNode())){ |
... | ... | |
310 | 310 |
if (!(nodoTocado.getUserObject() instanceof TocItemBranch)){ |
311 | 311 |
nodoTocado = (DefaultMutableTreeNode) nodoTocado.getParent(); |
312 | 312 |
} |
313 |
|
|
313 |
|
|
314 | 314 |
///posActual = oldParent.getIndex(getSelectedNode()); |
315 | 315 |
//Destino |
316 | 316 |
DefaultMutableTreeNode destParent=null; |
317 |
|
|
317 |
|
|
318 | 318 |
if (((TocItemBranch)nodoTocado.getUserObject()).getLayer() instanceof FLayers){ |
319 | 319 |
//isContainer=true; |
320 | 320 |
newPos=0; |
... | ... | |
323 | 323 |
destParent= (DefaultMutableTreeNode)nodoTocado.getParent(); |
324 | 324 |
newPos=destParent.getIndex(nodoTocado); |
325 | 325 |
} |
326 |
|
|
327 |
|
|
328 |
|
|
329 | 326 |
|
327 |
|
|
328 |
|
|
329 |
|
|
330 | 330 |
int action = e.getDropAction(); |
331 | 331 |
boolean copyAction = (action == DnDConstants.ACTION_COPY); |
332 | 332 |
|
... | ... | |
334 | 334 |
DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(childInfo); |
335 | 335 |
if (getSelectedNode().getAllowsChildren()){ |
336 | 336 |
int childs=getSelectedNode().getChildCount(); |
337 |
|
|
337 |
|
|
338 | 338 |
for (int i=0;i<childs;i++){ |
339 | 339 |
newChild.add((MutableTreeNode)getSelectedNode().getChildAt(0)); |
340 | 340 |
} |
341 | 341 |
} |
342 |
|
|
343 |
try {
|
|
342 |
|
|
343 |
try { |
|
344 | 344 |
if (!copyAction){ |
345 | 345 |
oldParent.remove(getSelectedNode()); |
346 | 346 |
destParent.insert(newChild,newPos); |
... | ... | |
352 | 352 |
catch (java.lang.IllegalStateException ils) { |
353 | 353 |
e.rejectDrop(); |
354 | 354 |
} |
355 |
|
|
355 |
|
|
356 | 356 |
e.getDropTargetContext().dropComplete(true); |
357 |
|
|
357 |
|
|
358 | 358 |
//expand nodes appropriately - this probably isnt the best way... |
359 |
|
|
359 |
|
|
360 | 360 |
// TODO: COMENTADO POR FJP |
361 | 361 |
/* com.iver.andami.ui.mdiManager.View[] views=PluginServices.getMDIManager().getAllViews(); |
362 | 362 |
for(int i=0;i<views.length;i++){ |
... | ... | |
364 | 364 |
((DefaultTreeModel)((View)views[i]).getTOC().getTree().getModel()).reload(oldParent); |
365 | 365 |
} |
366 | 366 |
} */ |
367 |
|
|
368 |
|
|
369 |
|
|
367 |
|
|
368 |
|
|
369 |
|
|
370 | 370 |
// ((DefaultTreeModel)model1).reload(oldParent); |
371 | 371 |
DefaultTreeModel model = (DefaultTreeModel) getModel(); |
372 | 372 |
model.reload(destParent); |
373 | 373 |
FLayers lpo=null; |
374 | 374 |
FLayers lpd=null; |
375 |
|
|
375 |
|
|
376 | 376 |
if (oldParent.getUserObject() instanceof TocItemBranch){ |
377 | 377 |
lpo=(FLayers)((TocItemBranch)oldParent.getUserObject()).getLayer(); |
378 | 378 |
//lpd=(FLayers)((TocItemBranch)destParent.getUserObject()).getLayer(); |
... | ... | |
386 | 386 |
}else{ |
387 | 387 |
lpd=((TocItemBranch)nodoTocado.getUserObject()).getLayer().getParentLayer(); |
388 | 388 |
} |
389 |
|
|
390 |
|
|
389 |
|
|
390 |
|
|
391 | 391 |
if (destParent.equals(oldParent)){ |
392 | 392 |
callListeners(oldPos,newPos,lpd); |
393 | 393 |
}else{ |
394 | 394 |
callListeners(lpo,lpd,((TocItemBranch)newChild.getUserObject()).getLayer()); |
395 | 395 |
} |
396 | 396 |
} |
397 |
|
|
397 |
|
|
398 | 398 |
catch (IOException io) { e.rejectDrop(); } |
399 | 399 |
catch (UnsupportedFlavorException ufe) {e.rejectDrop();} |
400 | 400 |
} //end of method |
401 | 401 |
public void dropRoot(TreeNode tn){ |
402 | 402 |
int oldPos,newPos; |
403 | 403 |
DefaultMutableTreeNode nodoTocado = |
404 |
(DefaultMutableTreeNode) tn;
|
|
404 |
(DefaultMutableTreeNode) tn; |
|
405 | 405 |
// get old parent node |
406 |
if (getSelectedNode()==null)return;
|
|
406 |
if (getSelectedNode()==null)return; |
|
407 | 407 |
DefaultMutableTreeNode oldParent = (DefaultMutableTreeNode) getSelectedNode().getParent(); |
408 | 408 |
if (oldParent!=null){ |
409 | 409 |
oldPos = oldParent.getIndex(getSelectedNode()); |
... | ... | |
411 | 411 |
DefaultMutableTreeNode destParent=null; |
412 | 412 |
newPos=0; |
413 | 413 |
destParent=nodoTocado; |
414 |
|
|
414 |
|
|
415 | 415 |
//make new child node |
416 | 416 |
DefaultMutableTreeNode newChild = (DefaultMutableTreeNode)getSelectedNode().clone(); |
417 | 417 |
oldParent.remove(getSelectedNode()); |
418 | 418 |
destParent.insert(newChild,newPos); |
419 |
|
|
419 |
|
|
420 | 420 |
com.iver.andami.ui.mdiManager.IWindow[] views=PluginServices.getMDIManager().getAllWindows(); |
421 | 421 |
for(int i=0;i<views.length;i++){ |
422 | 422 |
if (views[i] instanceof View){ |
... | ... | |
428 | 428 |
model.reload(destParent); |
429 | 429 |
FLayers lpo=null; |
430 | 430 |
FLayers lpd=null; |
431 |
|
|
431 |
|
|
432 | 432 |
lpo=(FLayers)((TocItemBranch)getSelectedNode().getUserObject()).getLayer().getParentLayer(); |
433 | 433 |
for(int i=0;i<views.length;i++){ |
434 | 434 |
if (views[i] instanceof View){ |
... | ... | |
450 | 450 |
} |
451 | 451 |
|
452 | 452 |
/** DropTaregetListener interface method */ |
453 |
public void dragExit(DropTargetEvent e) {
|
|
453 |
public void dragExit(DropTargetEvent e) { |
|
454 | 454 |
} |
455 | 455 |
|
456 | 456 |
/** DropTaregetListener interface method */ |
... | ... | |
458 | 458 |
/* ********************** CHANGED ********************** */ |
459 | 459 |
//set cursor location. Needed in setCursor method |
460 | 460 |
Point cursorLocationBis = e.getLocation(); |
461 |
TreePath destinationPath =
|
|
461 |
TreePath destinationPath = |
|
462 | 462 |
getPathForLocation(cursorLocationBis.x, cursorLocationBis.y); |
463 | 463 |
|
464 | 464 |
|
465 | 465 |
// if destination path is okay accept drop... |
466 |
|
|
466 |
|
|
467 | 467 |
if (testSameComponent(e)) |
468 | 468 |
{ |
469 | 469 |
String msg = testDropTarget(destinationPath, SelectedTreePath); |
470 |
if ( msg == null) {
|
|
470 |
if ( msg == null) { |
|
471 | 471 |
e.acceptDrag(DnDConstants.ACTION_MOVE) ; |
472 | 472 |
return; |
473 | 473 |
} |
474 |
|
|
474 |
|
|
475 | 475 |
} |
476 | 476 |
// ...otherwise reject drop |
477 | 477 |
// else { |
478 | 478 |
// System.err.println(e.getDropTargetContext().getComponent()); |
479 |
|
|
479 |
|
|
480 | 480 |
// if (testSameComponent(e)) |
481 | 481 |
e.rejectDrag() ; |
482 |
/* else
|
|
482 |
/* else |
|
483 | 483 |
e.acceptDrag(DnDConstants.ACTION_MOVE); */ |
484 | 484 |
// } |
485 | 485 |
/* ****************** END OF CHANGE ******************** */ |
... | ... | |
514 | 514 |
} |
515 | 515 |
|
516 | 516 |
/** Convenience method to test whether drop location is valid |
517 |
@param destination The destination path
|
|
517 |
@param destination The destination path |
|
518 | 518 |
@param dropper The path for the node to be dropped |
519 | 519 |
@return null if no problems, otherwise an explanation |
520 | 520 |
*/ |
521 | 521 |
private String testDropTarget(TreePath destination, TreePath dropper) { |
522 | 522 |
//Typical Tests for dropping |
523 |
|
|
523 |
|
|
524 | 524 |
//Test 1. |
525 | 525 |
boolean destinationPathIsNull = destination == null; |
526 |
if (destinationPathIsNull)
|
|
526 |
if (destinationPathIsNull) |
|
527 | 527 |
return "Invalid drop location."; |
528 | 528 |
|
529 | 529 |
//Test 2. |
... | ... | |
535 | 535 |
return "Destination cannot be same as source"; |
536 | 536 |
|
537 | 537 |
//Test 3. |
538 |
/* if ( dropper.isDescendant(destination))
|
|
538 |
/* if ( dropper.isDescendant(destination)) |
|
539 | 539 |
return "Destination node cannot be a descendant."; |
540 | 540 |
|
541 | 541 |
//Test 4. |
542 |
if ( dropper.getParentPath().equals(destination))
|
|
542 |
if ( dropper.getParentPath().equals(destination)) |
|
543 | 543 |
return "Destination node cannot be a parent."; */ |
544 | 544 |
|
545 | 545 |
return null; |
... | ... | |
566 | 566 |
} |
567 | 567 |
private void callListeners(int oldPos, int newPos,FLayers lpd) |
568 | 568 |
{ |
569 |
lpd.getMapContext().clearAllCachingImageDrawnLayers(); |
|
569 | 570 |
for (int i=0; i < m_Listeners.size(); i++) |
570 | 571 |
{ |
571 | 572 |
ITocOrderListener listener = (ITocOrderListener) m_Listeners.get(i); |
572 | 573 |
listener.orderChanged(oldPos, newPos,lpd); |
573 | 574 |
} |
575 |
|
|
574 | 576 |
} |
575 |
|
|
577 |
|
|
576 | 578 |
private void callListeners(FLayers lpo,FLayers lpd,FLayer ls){ |
579 |
lpo.getMapContext().clearAllCachingImageDrawnLayers(); |
|
577 | 580 |
for (int i=0; i < m_Listeners.size(); i++) |
578 | 581 |
{ |
579 | 582 |
ITocOrderListener listener = (ITocOrderListener) m_Listeners.get(i); |
580 | 583 |
listener.parentChanged(lpo,lpd,ls); |
581 | 584 |
} |
585 |
|
|
582 | 586 |
} |
583 | 587 |
|
584 | 588 |
} //end of DnDJTree |
Also available in: Unified diff