📄 treeviewdraganddrop.java
字号:
/* * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product that is * described in this document. In particular, and without limitation, these intellectual property rights may * include one or more of the U.S. patents listed at http://www.sun.com/patents and one or more additional patents * or pending patent applications in the U.S. and in other countries. * * U.S. Government Rights - Commercial software. Government users are subject to the Sun Microsystems, Inc. * standard license agreement and applicable provisions of the FAR and its supplements. * * Use is subject to license terms. * * This distribution may include materials developed by third parties. Sun, Sun Microsystems, the Sun logo and * Java are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. * * Copyright (c) 2006 Sun Microsystems, Inc. Tous droits r?serv?s. * * Sun Microsystems, Inc. d?tient les droits de propri?t? intellectuels relatifs ? la technologie incorpor?e dans * le produit qui est d?crit dans ce document. En particulier, et ce sans limitation, ces droits de propri?t? * intellectuelle peuvent inclure un ou plus des brevets am?ricains list?s ? l'adresse http://www.sun.com/patents * et un ou les brevets suppl?mentaires ou les applications de brevet en attente aux Etats - Unis et dans les * autres pays. * * L'utilisation est soumise aux termes du contrat de licence. * * Cette distribution peut comprendre des composants d?velopp?s par des tierces parties. * Sun, Sun Microsystems, le logo Sun et Java sont des marques de fabrique ou des marques d?pos?es de Sun * Microsystems, Inc. aux Etats-Unis et dans d'autres pays. */package com.sun.spot.spotworld.treeview;import com.sun.spot.spotworld.participants.Application;import com.sun.spot.spotworld.participants.SquawkHost;import java.awt.Point;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;import java.awt.datatransfer.UnsupportedFlavorException;import java.awt.dnd.DnDConstants;import java.awt.dnd.DragGestureEvent;import java.awt.dnd.DragGestureListener;import java.awt.dnd.DragGestureRecognizer;import java.awt.dnd.DragSource;import java.awt.dnd.DragSourceDragEvent;import java.awt.dnd.DragSourceDropEvent;import java.awt.dnd.DragSourceEvent;import java.awt.dnd.DragSourceListener;import java.awt.dnd.DropTarget;import java.awt.dnd.DropTargetContext;import java.awt.dnd.DropTargetDragEvent;import java.awt.dnd.DropTargetDropEvent;import java.awt.dnd.DropTargetEvent;import java.awt.dnd.DropTargetListener;import java.io.IOException;import java.util.Enumeration;import java.util.Vector;import javax.swing.JTree;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.DefaultTreeModel;import javax.swing.tree.TreeNode;import javax.swing.tree.TreePath;/** * * @author taylorr */public class TreeViewDragAndDrop implements DragGestureListener, DropTargetListener, DragSourceListener { private JTree tree = null; // Drag stuff private DragSource source = null; private DragGestureRecognizer recognise = null; private TransferableTreePath transferable = null; private Vector<TVObject> oldNode = null; // Drop stuff private DropTarget target = null; public TreeViewDragAndDrop(JTree tree, int actions) { this.tree = tree; // init drag stuff source = new DragSource(); recognise = source.createDefaultDragGestureRecognizer(tree, actions, this); // init drop stuff target = new DropTarget(tree, this); } // Drag Gesture Listener methods // Start of the drag and drop stuff public void dragGestureRecognized(DragGestureEvent dragEvent) { oldNode = new Vector<TVObject>(); // Get what is selected TreePath path = tree.getSelectionPath(); // reject if you're dragging nothing or trying to drag the tree root if ((path == null) || (path.getPathCount() <= 1)) return; // store a reference to what's selected oldNode.addElement((TVObject) path.getLastPathComponent()); // start the drag source.startDrag(dragEvent, DragSource.DefaultMoveNoDrop, new TransferableTreePath(), this); } // Drag Source Listener methods public void dragEnter(DragSourceDragEvent dragSourceDragEvent) { } public void dragOver(DragSourceDragEvent dragSourceDragEvent) { } public void dropActionChanged(DragSourceDragEvent dragSourceDragEvent) { } public void dragExit(DragSourceEvent dragSourceEvent) { } public void dragDropEnd(DragSourceDropEvent dragSourceDropEvent) { } // Drop Target Listener methods public void dragEnter(DropTargetDragEvent dragEvent) { } // Is called when dragged over a TVObject in the view public void dragOver(DropTargetDragEvent dragEvent) { // See if we can accept the drop if (acceptDrop(getNodeForEvent(dragEvent)) && !((DefaultMutableTreeNode) getNodeForEvent(dragEvent)).isNodeAncestor(oldNode.elementAt(0))) { dragEvent.acceptDrag(DnDConstants.ACTION_MOVE); // If we're over a collapsed node, expand Point p = dragEvent.getLocation(); DropTargetContext context = dragEvent.getDropTargetContext(); JTree tree = (JTree) context.getComponent(); TreePath parentPath = tree.getClosestPathForLocation(p.x, p.y); tree.expandPath(parentPath); } dragEvent.rejectDrag(); } // Determines what can be dropped on a view private boolean acceptDrop(TreeNode treeNode) { // Get the TVObject we're dragging TVObject element = (TVObject) oldNode.elementAt(0); // if we're dragging a TVSquawkHost or a TVGroup object we can only // drop it on another group or TVSPOTWorld if ((treeNode instanceof TVGroup || treeNode instanceof TVSPOTWorld) && (element instanceof TVSquawkHost || element instanceof TVGroup)) return true; // if we're dragging a TVApplication we can only drop it on a TVSquawkHost else if (treeNode instanceof TVSquawkHost && element instanceof TVApplication) return true; // else reject else return false; } public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { } public void dragExit(DropTargetEvent dropTargetEvent) { } public void drop(DropTargetDropEvent dropEvent) { // Get the Object and Path we've dropped on Point p = dropEvent.getLocation(); DropTargetContext context = dropEvent.getDropTargetContext(); JTree tree = (JTree) context.getComponent(); TreePath parentPath = tree.getClosestPathForLocation(p.x, p.y); TVObject parent = (TVObject) parentPath.getLastPathComponent(); // Make sure we can drop here if (!acceptDrop(parent)) { dropEvent.rejectDrop(); return; } // Make sure the dragged objects are not ancestors of where we want to // drop them for (TVObject element : oldNode) { if (parent.isNodeAncestor(element)) { dropEvent.rejectDrop(); return; } } try { Transferable transferable = dropEvent.getTransferable(); DataFlavor[] flavours = transferable.getTransferDataFlavors(); for (int i = 0; i < flavours.length; i++) { // Did we drop a TreePath object if (transferable.isDataFlavorSupported(flavours[i])) { dropEvent.acceptDrop(DnDConstants.ACTION_MOVE); TreePath path = (TreePath) transferable.getTransferData(flavours[i]); // Get the TVObject we dragged. Yes I know this isn't the proper // way to do things TVObject element = (TVObject) oldNode.elementAt(0).clone(); // Before we delete it from the tree record if the TVObject and it's // children are collapsed/expanded. Vector<TVObject> applications = new Vector<TVObject>(); for (Enumeration e = element.breadthFirstEnumeration(); e.hasMoreElements();) { TVObject tvObject = (TVObject) e.nextElement(); if (tree.isVisible(new TreePath(tvObject.getPath()))) applications.addElement(tvObject); } if (element instanceof TVApplication) // We don't want two copies of an app hanging around. ((DefaultTreeModel) tree.getModel()).removeNodeFromParent(element); ((DefaultTreeModel) tree.getModel()).insertNodeInto((TVObject) element, parent, 0); // If it was selected, select it again if (element.isSelected()) tree.addSelectionPath(new TreePath(element.getPath())); // restore TVObject collapse/expand state for (TVObject tvObject : applications) { tree.scrollPathToVisible(new TreePath(tvObject.getPath())); if (tvObject.isSelected()) tree.addSelectionPath(new TreePath(tvObject.getPath())); } // If we've moved an Application tell everybody else about it if (element instanceof TVApplication) { SquawkHost host = (SquawkHost) parent.getVirtualObject(); Application app = (Application) ((TVApplication) element).getVirtualObject(); app.setHost(host); } // And we're done dropEvent.dropComplete(true); return; } dropEvent.rejectDrop(); } } catch (Exception e) { e.printStackTrace(); dropEvent.rejectDrop(); } } private TreeNode getNodeForEvent(DropTargetDragEvent dragEvent) { Point p = dragEvent.getLocation(); DropTargetContext context = dragEvent.getDropTargetContext(); JTree tree = (JTree) context.getComponent(); TreePath path = tree.getClosestPathForLocation(p.x, p.y); return (TreeNode) path.getLastPathComponent(); } // This class in theory holds the serialised object(s?) that are being dragged // since we don't serialise TVObjects (yet) this is just used to get the // appropriate data flavors. private class TransferableTreePath implements Transferable { private DataFlavor TREE_PATH_FLAVOR = new DataFlavor(TreePath.class, "Tree Path"); private DataFlavor flavors[] = { TREE_PATH_FLAVOR }; private TreePath path; public TransferableTreePath() { } // TVObject object graph must be completely serialisable for this to work// public TransferableTreePath(TreePath tp) { path = tp; } public DataFlavor[] getTransferDataFlavors() { return flavors; } public boolean isDataFlavorSupported(DataFlavor flavor) { return (flavor.getRepresentationClass() == TreePath.class); } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (isDataFlavorSupported(flavor)) return (Object) path; else throw new UnsupportedFlavorException(flavor); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -