package com.moya.test;/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O'Reilly *///TreeDragTest.java//A simple starting point for testing the DnD JTree code.//import java.awt.BorderLayout;import java.awt.Color;import java.awt.Graphics;import java.awt.Insets;import java.awt.Point;import java.awt.Rectangle;import java.awt.datatransfer.DataFlavor;import java.awt.datatransfer.Transferable;import java.awt.datatransfer.UnsupportedFlavorException;import java.awt.dnd.Autoscroll;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 javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTree;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.DefaultTreeModel;import javax.swing.tree.TreeNode;import javax.swing.tree.TreePath;public class TreeDragTest extends JFrame {TreeDragSource ds;TreeDropTarget dt;JTree tree;public TreeDragTest() {super("Rearrangeable Tree");setSize(300, 200);setDefaultCloseOperation(EXIT_ON_CLOSE);// If you want autoscrolling, use this line:tree = new AutoScrollingJTree();// Otherwise, use this line:// tree = new JTree();getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);// If we only support move operations...// ds = new TreeDragSource(tree, DnDConstants.ACTION_MOVE);ds = new TreeDragSource(tree, DnDConstants.ACTION_COPY_OR_MOVE);dt = new TreeDropTarget(tree);setVisible(true);}public class AutoScrollingJTree extends JTree implements Autoscroll {private int margin = 12;public AutoScrollingJTree() {super();}public void autoscroll(Point p) {int realrow = getRowForLocation(p.x, p.y);Rectangle outer = getBounds();realrow = (p.y + outer.y <= margin ? realrow < 1 ? 0 : realrow - 1 : realrow < getRowCount() - 1 ? realrow + 1 : realrow);scrollRowToVisible(realrow);}public Insets getAutoscrollInsets() {Rectangle outer = getBounds();Rectangle inner = getParent().getBounds();return new Insets(inner.y - outer.y + margin, inner.x - outer.x + margin, outer.height - inner.height - inner.y + outer.y + margin, outer.width - inner.width - inner.x + outer.x + margin);}// Use this method if you want to see the boundaries of the// autoscroll active regionpublic void paintComponent(Graphics g) {super.paintComponent(g);Rectangle outer = getBounds();Rectangle inner = getParent().getBounds();g.setColor(Color.red);g.drawRect(-outer.x + 12, -outer.y + 12, inner.width - 24, inner.height - 24);}}public static void main(String args[]) {new TreeDragTest();}}// TreeDragSource.java// A drag source wrapper for a JTree. This class can be used to make// a rearrangeable DnD tree with the TransferableTreeNode class as the// transfer data type.class TreeDragSource implements DragSourceListener, DragGestureListener {DragSource source;DragGestureRecognizer recognizer;TransferableTreeNode transferable;DefaultMutableTreeNode oldNode;JTree sourceTree;public TreeDragSource(JTree tree, int actions) {sourceTree = tree;source = new DragSource();recognizer = source.createDefaultDragGestureRecognizer(sourceTree, actions, this);}/* * Drag Gesture Handler */public void dragGestureRecognized(DragGestureEvent dge) {TreePath path = sourceTree.getSelectionPath();if ((path == null) || (path.getPathCount() <= 1)) {// We can't move the root node or an empty selectionreturn;}oldNode = (DefaultMutableTreeNode) path.getLastPathComponent();transferable = new TransferableTreeNode(path);source.startDrag(dge, DragSource.DefaultMoveNoDrop, transferable, this);// If you support dropping the node anywhere, you should probably// start with a valid move cursor:// source.startDrag(dge, DragSource.DefaultMoveDrop, transferable,// this);}/* * Drag Event Handlers */public void dragEnter(DragSourceDragEvent dsde) {}public void dragExit(DragSourceEvent dse) {}public void dragOver(DragSourceDragEvent dsde) {}public void dropActionChanged(DragSourceDragEvent dsde) {System.out.println("Action: " + dsde.getDropAction());System.out.println("Target Action: " + dsde.getTargetActions());System.out.println("User Action: " + dsde.getUserAction());}public void dragDropEnd(DragSourceDropEvent dsde) {/* * to support move or copy, we have to check which occurred: */System.out.println("Drop Action: " + dsde.getDropAction());if (dsde.getDropSuccess() && (dsde.getDropAction() == DnDConstants.ACTION_MOVE)) {((DefaultTreeModel) sourceTree.getModel()).removeNodeFromParent(oldNode);}/* * to support move only... if (dsde.getDropSuccess()) { * ((DefaultTreeModel * )sourceTree.getModel()).removeNodeFromParent(oldNode); } */}}// TreeDropTarget.java// A quick DropTarget that's looking for drops from draggable JTrees.//class TreeDropTarget implements DropTargetListener {DropTarget target;JTree targetTree;public TreeDropTarget(JTree tree) {targetTree = tree;target = new DropTarget(targetTree, this);}/* * Drop Event Handlers */private TreeNode getNodeForEvent(DropTargetDragEvent dtde) {Point p = dtde.getLocation();DropTargetContext dtc = dtde.getDropTargetContext();JTree tree = (JTree) dtc.getComponent();TreePath path = tree.getClosestPathForLocation(p.x, p.y);return (TreeNode) path.getLastPathComponent();}public void dragEnter(DropTargetDragEvent dtde) {TreeNode node = getNodeForEvent(dtde);if (node.isLeaf()) {dtde.rejectDrag();} else {// start by supporting move operations// dtde.acceptDrag(DnDConstants.ACTION_MOVE);dtde.acceptDrag(dtde.getDropAction());}}public void dragOver(DropTargetDragEvent dtde) {TreeNode node = getNodeForEvent(dtde);if (node.isLeaf()) {dtde.rejectDrag();} else {// start by supporting move operations// dtde.acceptDrag(DnDConstants.ACTION_MOVE);dtde.acceptDrag(dtde.getDropAction());}}public void dragExit(DropTargetEvent dte) {}public void dropActionChanged(DropTargetDragEvent dtde) {}public void drop(DropTargetDropEvent dtde) {Point pt = dtde.getLocation();DropTargetContext dtc = dtde.getDropTargetContext();JTree tree = (JTree) dtc.getComponent();TreePath parentpath = tree.getClosestPathForLocation(pt.x, pt.y);DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentpath.getLastPathComponent();if (parent.isLeaf()) {dtde.rejectDrop();return;}try {Transferable tr = dtde.getTransferable();DataFlavor[] flavors = tr.getTransferDataFlavors();for (int i = 0; i < flavors.length; i++) {if (tr.isDataFlavorSupported(flavors[i])) {dtde.acceptDrop(dtde.getDropAction());TreePath p = (TreePath) tr.getTransferData(flavors[i]);DefaultMutableTreeNode node = (DefaultMutableTreeNode) p.getLastPathComponent();DefaultTreeModel model = (DefaultTreeModel) tree.getModel();model.insertNodeInto(node, parent, 0);dtde.dropComplete(true);return;}}dtde.rejectDrop();} catch (Exception e) {e.printStackTrace();dtde.rejectDrop();}}}// TransferableTreeNode.java// A Transferable TreePath to be used with Drag & Drop applications.//class TransferableTreeNode implements Transferable {public static DataFlavor TREE_PATH_FLAVOR = new DataFlavor(TreePath.class, "Tree Path");DataFlavor flavors[] = { TREE_PATH_FLAVOR };TreePath path;public TransferableTreeNode(TreePath tp) {path = tp;}public synchronized DataFlavor[] getTransferDataFlavors() {return flavors;}public boolean isDataFlavorSupported(DataFlavor flavor) {return (flavor.getRepresentationClass() == TreePath.class);}public synchronized Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {if (isDataFlavorSupported(flavor)) {return (Object) path;} else {throw new UnsupportedFlavorException(flavor);}}}