/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.explorer.view; import java.awt.dnd.*; import java.awt.Point; import java.util.Arrays; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.*; import javax.swing.event.TreeSelectionEvent; import org.openide.nodes.Node; import org.openide.explorer.ExplorerPanel; /** Support for the drag operations in the TreeView. * * @author Dafe Simonek, Jiri Rechtacek */ final class TreeViewDragSupport extends ExplorerDragSupport { // Attributes /** True when we are active, false otherwise */ boolean active = false; /** Recognizes default gesture */ DragGestureRecognizer defaultGesture; /** Holds content of the selection in tree. * It's here only for workaround of sun's bug */ TreePath[] curSelection; TreePath[] oldSelection; // Associations /** The view that manages viewing the data in a tree. */ protected TreeView view; /** The tree which we are supporting (our client) */ private JTree tree; /** Cell renderer - PENDING - do we need it? */ //protected DnDTreeViewCellRenderer cellRenderer; // Operations /** Creates new TreeViewDragSupport, initializes gesture */ public TreeViewDragSupport(TreeView view, JTree tree) { this.view = view; this.comp = tree; this.tree = tree; } public void dragGestureRecognized (DragGestureEvent dge) { super.dragGestureRecognized (dge); // notify tree cell editor that DnD operationm is active if (exDnD.isDnDActive ()) { TreeCellEditor tce = ((JTree)tree).getCellEditor (); if (tce instanceof TreeViewCellEditor) ((TreeViewCellEditor)tce).setDnDActive (true); } } public void dragDropEnd (DragSourceDropEvent dsde) { // get the droped nodes Node[] dropedNodes = exDnD.getDraggedNodes (); super.dragDropEnd (dsde); // if any original glass pane was stored (the DnD was broken e.g. by Esc) if (DropGlassPane.isOriginalPaneStored ()) { // give back the orig glass pane DropGlassPane.putBackOriginal (); // DnD is not active exDnD.setDnDActive (false); } // select the droped nodes try { if (dropedNodes!=null) { ExplorerPanel panel = (ExplorerPanel)SwingUtilities .getAncestorOfClass(ExplorerPanel.class, view); if (panel!=null) { panel.getExplorerManager ().setSelectedNodes (dropedNodes); } } } catch (Exception e) { // don't care } // notify tree cell editor that DnD operationm is active // no more TreeCellEditor tce = tree.getCellEditor(); if (tce instanceof TreeViewCellEditor) ((TreeViewCellEditor)tce).setDnDActive (false); } /** Utility method. Returns either selected nodes in tree * (if cursor hotspot is above some selected node) or the node * the cursor points to. * @return Node array or null if position of the cursor points * to no node. */ Node[] obtainNodes (DragGestureEvent dge) { Point dragOrigin = dge.getDragOrigin(); TreePath tp = tree.getPathForLocation(dragOrigin.x, dragOrigin.y); if (tp==null) return null; Node n=DragDropUtilities.secureFindNode(tp.getLastPathComponent()); if (n==null) return null; // workaround for Sun's bug #4165577 // we must repair the selection before dragging if ((oldSelection != null) && wasSelected(n)) { tree.setSelectionPaths(oldSelection); curSelection = null; } // ---end of workaround Node[] result = null; if (tree.isPathSelected(tp)) { // cursor above selected, so return all selected nodes TreePath[] tps = tree.getSelectionPaths(); result = new Node[tps.length]; for (int i = 0; i < tps.length; i++) { result[i]=DragDropUtilities.secureFindNode(tps[i].getLastPathComponent()); if (result[i]==null) return null; } } else { // return only the node the cursor is above result = new Node[] { n }; } return result; } /** Stores last two selections. * Workaround for sun's bug */ public void valueChanged (TreeSelectionEvent tse) { TreePath[] newSelection = tree.getSelectionPaths(); if ((newSelection != null) && (!Arrays.equals(curSelection, newSelection))) { oldSelection = (curSelection == null) ? newSelection : curSelection; curSelection = newSelection; } } /** @return True if given object was selected in old selection, * false otherwise */ boolean wasSelected (Object obj) { if (oldSelection == null) return false; for (int i = 0; i < oldSelection.length; i++) { if (obj.equals(oldSelection[i].getLastPathComponent())) return true; } return false; } } /* end class TreeViewDragSupport */