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
|