2011-12-02 63 views
3

我有一個JTree,我想將一些文件從JTree導出到資源管理器。要做到這一點,我使用TransferHandler和風味:DataFlavor.javaFileListFlavor。所以,資源管理器可以導入拖動的文件。問題是我的文件在服務器上,當可移植對象放在資源管理器上時我需要下載它們。Drag n Drop:在將文件從組件拖放到資源管理器,查找程序等時的操作

如何在啓動瀏覽器時啓動我的下載方法?我怎樣才能知道我的下載文件的目標文件夾?

這裏的樣本:

import java.awt.BorderLayout; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

import javax.swing.BorderFactory; 
import javax.swing.DropMode; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.TransferHandler; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreePath; 
import javax.swing.tree.TreeSelectionModel; 


public class JTreeDnDSample extends JFrame 
{ 
    protected JTree _tree; 

    private DefaultTreeModel treeModel; 
    private DefaultMutableTreeNode rootNode; 

    private JScrollPane border; 

    public static void main(String[] args) 
    { 
     new JTreeDnDSample().setVisible(true); 
    } 

    public JTreeDnDSample() 
    { 
     super("Dnd"); 
     initializeTree(); 
     this.setLayout(new BorderLayout()); 

     border = new JScrollPane(this._tree); 
     border.setBorder(BorderFactory.createTitledBorder("Tree")); 
     this.add(border, BorderLayout.CENTER); 
     this.setSize(400, 800); 
    } 

    protected void initializeTree() 
    { 

     this.rootNode = new DefaultMutableTreeNode("Root folder"); 
     this.treeModel = new DefaultTreeModel(rootNode); 
     _tree = new JTree(treeModel); 


     _tree.setName("TREE"); 
     _tree.setDragEnabled(true); 
     _tree.setDropMode(DropMode.ON_OR_INSERT); 
     _tree.setTransferHandler(new TreeTransferHandler()); 

     _tree.setShowsRootHandles(true); 
     _tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);  
     _tree.setRowHeight(26); 

     //tree creation 
     DefaultMutableTreeNode folder = new DefaultMutableTreeNode("folder1"); 
     DefaultMutableTreeNode file = new DefaultMutableTreeNode("file1.txt"); 
     folder.add(file); 
     file = new DefaultMutableTreeNode("file2.txt"); 
     folder.add(file); 
     rootNode.add(folder); 
     folder = new DefaultMutableTreeNode("folder2"); 
     file = new DefaultMutableTreeNode("file1.txt"); 
     folder.add(file); 
     file = new DefaultMutableTreeNode("file2.txt"); 
     folder.add(file); 
     file = new DefaultMutableTreeNode("file3.txt"); 
     folder.add(file); 
     rootNode.add(folder); 
    } 

    public void setTitle(String title) 
    { 
     border.setBorder(BorderFactory.createTitledBorder(title)); 
    } 
} 


class TreeTransferHandler extends TransferHandler 
{   
    private DataFlavor nodesFlavor; 
    private DataFlavor[] flavors = new DataFlavor[1]; 
    private DefaultMutableTreeNode[] nodesToRemove; 

    public TreeTransferHandler() 
    { 
     super(); 
     try 
     { 
      String mimeType = DataFlavor.javaJVMLocalObjectMimeType + 
      ";class=\"" + 
      DefaultMutableTreeNode[].class.getName() + 
      "\""; 
      nodesFlavor = new DataFlavor(mimeType); 
      flavors[0] = nodesFlavor; 
     } 
     catch(ClassNotFoundException e) 
     { 
      System.out.println("ClassNotFound: " + e.getMessage()); 
     } 
    } 

    public boolean importData(TransferHandler.TransferSupport support) 
    { 
     Transferable data = support.getTransferable(); 

     if(!canImport(support)) 
     { 
      return false; 
     } 
     // Extract transfer data. 
     List<DefaultMutableTreeNode> nodes = new ArrayList<DefaultMutableTreeNode>(); 
     try 
     { 
      System.out.println("IMPORT DATA"); 
      nodes = (List<DefaultMutableTreeNode>) data.getTransferData(nodesFlavor); 
      /*List<File> files = (List<File>)data.getTransferData(DataFlavor.javaFileListFlavor); 
      System.out.println("File size: " + nodes.size()); 
      for(File f : files) 
      { 
       System.out.println("File: "+f.getName()); 
      }*/ 
     } 
     catch(UnsupportedFlavorException ufe) 
     { 
      System.out.println("UnsupportedFlavor: " + ufe.getMessage()); 
     } 
     catch(java.io.IOException ioe) 
     { 
      System.out.println("I/O error: " + ioe.getMessage()); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
     // Get drop location info inside the tree. 
     JTree.DropLocation dl = 
      (JTree.DropLocation)support.getDropLocation(); 
     int childIndex = dl.getChildIndex(); 
     TreePath dest = dl.getPath(); 
     DefaultMutableTreeNode parent = (DefaultMutableTreeNode)dest.getLastPathComponent(); 
     JTree tree = (JTree)support.getComponent(); 
     DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); 
     // Configure for drop mode. 
     int index = childIndex; // DropMode.INSERT 
     if(childIndex == -1) // DropMode.ON 
      index = parent.getChildCount(); 

     // Add data to model. 
     for(int i = 0; i < nodes.size(); i++) 
     { 
      model.insertNodeInto(nodes.get(i), parent, index++); 
     } 

     // Remove nodes saved in nodesToRemove in createTransferable. 
     for(int i = 0; i < nodesToRemove.length; i++) 
     { 
      model.removeNodeFromParent(nodesToRemove[i]); 
     } 
     return true; 

    } 

    public boolean canImport(TransferHandler.TransferSupport support) 
    { 
     if(!support.isDrop()) 
      return false; 

     support.setShowDropLocation(true); 
     if(!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor) 
       && !support.isDataFlavorSupported(nodesFlavor)) 
      return false; 

     // Do not allow a drop on the drag source selections. 
     JTree.DropLocation dl = (JTree.DropLocation)support.getDropLocation(); 
     JTree tree = (JTree)support.getComponent(); 
     int dropRow = tree.getRowForPath(dl.getPath()); 
     int[] selRows = tree.getSelectionRows(); 
     if(selRows != null) 
     { 
      for(int i = 0; i < selRows.length; i++) 
      { 
       if(selRows[i] == dropRow) 
        return false; 
      } 
     } 
     //Do not allow a drop on a File (leaf) 
     try 
     { 
      TreePath targetPath = tree.getDropLocation().getPath(); 
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) targetPath.getLastPathComponent(); 
      if(node.isLeaf()) 
      { 
       return false; 
      } 
     } 
     catch(Exception ex) 
     { 
      System.out.println(ex.getMessage()); 
      return false; 
     } 
     // Do not allow a non-leaf node to be copied to a level 
     // which is less than its source level. 
     TreePath dest = dl.getPath(); 
     DefaultMutableTreeNode target = (DefaultMutableTreeNode)dest.getLastPathComponent(); 
     TreePath path = tree.getPathForRow(selRows[0]); 
     DefaultMutableTreeNode firstNode = (DefaultMutableTreeNode)path.getLastPathComponent(); 
     if(firstNode.getChildCount() > 0 && target.getLevel() < firstNode.getLevel()) 
     { 
      return false; 
     } 
     return true; 
    } 


    //Do i have to use exportDone ? 
    protected void exportDone(JComponent source, Transferable data, int action) 
    { 
     if((action & MOVE) == MOVE) 
     { 
      //GET THE FILE DESTINATION FOLDER 
      //LAUNCH THE DOWNLOAD FILE PROCESS 
     } 
    } 

    protected Transferable createTransferable(JComponent c) 
    { 
     JTree tree = (JTree)c; 
     TreePath[] paths = tree.getSelectionPaths(); 
     if(paths != null) 
     { 
      // Make up a node array of copies for transfer and 
      // another for/of the nodes that will be removed in 
      // exportDone after a successful drop. 
      ArrayList<DefaultMutableTreeNode> copies = new ArrayList<DefaultMutableTreeNode>(); 
      ArrayList<DefaultMutableTreeNode> toRemove = new ArrayList<DefaultMutableTreeNode>(); 

      //Fake files created in order to allow the export on explorer 
      ArrayList<File> fakeFiles = new ArrayList<File>(); 

      DefaultMutableTreeNode node = (DefaultMutableTreeNode)paths[0].getLastPathComponent(); 
      DefaultMutableTreeNode copy = copy(node); 
      copies.add(copy); 
      toRemove.add(node); 
      for(int i = 1; i < paths.length; i++) 
      { 
       DefaultMutableTreeNode next = (DefaultMutableTreeNode)paths[i].getLastPathComponent(); 
       // Do not allow higher level nodes to be added to list. 
       if(next.getLevel() < node.getLevel()) 
       { 
        break; 
       } 
       else if(next.getLevel() > node.getLevel()) 
       { // child node 
        copy.add(copy(next)); 
        // node already contains child 
       } 
       else 
       {          // sibling 
        copies.add(copy(next)); 
        toRemove.add(next); 
       } 
      } 
      DefaultMutableTreeNode[] nodesToMove = copies.toArray(new DefaultMutableTreeNode[copies.size()]); 
      for(DefaultMutableTreeNode n : nodesToMove) 
      { 
       File f = new File(n.toString()); 
       fakeFiles.add(f); 
      } 
      nodesToRemove = toRemove.toArray(new DefaultMutableTreeNode[toRemove.size()]); 


      return new NodesTransferable(fakeFiles, Arrays.asList(nodesToMove)); 
     } 
     return null; 
    } 

    /** Defensive copy used in createTransferable. */ 
    private DefaultMutableTreeNode copy(DefaultMutableTreeNode node) 
    { 
     return new DefaultMutableTreeNode(node); 
    } 

    public int getSourceActions(JComponent c) 
    { 
     return COPY_OR_MOVE; 
    } 

    public class NodesTransferable implements Transferable 
    { 
     private List<File> data = null; 
     private List<DefaultMutableTreeNode> nodes = null; 
     private DataFlavor[] flavors = new DataFlavor[2]; 
     public NodesTransferable(final List<File> data, final List<DefaultMutableTreeNode> nodes) 
     { 
      super(); 
      this.data = data; 
      this.nodes = nodes; 
      flavors[0] = DataFlavor.javaFileListFlavor; 
      flavors[1] = nodesFlavor; 
     } 
     public DataFlavor[] getTransferDataFlavors() 
     { 
      return flavors; 
     } 
     public boolean isDataFlavorSupported(final DataFlavor flavor) 
     { 
      return true; 
     } 
     public List<?> getTransferData(final DataFlavor flavor) throws UnsupportedFlavorException, IOException 
     { 
      if(flavor.equals(DataFlavor.javaFileListFlavor)) 
       return data; 
      else if(flavor.equals(nodesFlavor)) 
       return nodes; 
      else 
      { 
       System.out.println("Unsuported flavor"); 
       return null; 
      } 
     } 
    } 
} 

回答

0

我可能是錯誤的,但我不相信有反正Java客戶端知道,一滴發生JVM之外。我相信拖放合同是每個客戶端(程序)負責在拖動開始時推出數據,並在發生拖放時提取數據。您需要查看是否有資源管理器中的庫向您通知此丟失。

看着互聯網,它看起來像這個例子:http://www.codeproject.com/Articles/591/Drag-And-Drop-between-JList-and-Windows-Explorer顯示瞭如何在JList和資源管理器之間做到這一點。被警告,我沒有機會嘗試這個看看它是否會起作用。它看起來像有一個的DataFlavor:

DataFlavor.javaFileListFlavor 

這裏的另一篇文章,描述類似的東西:Swing application -> Drag & drop to the desktop/folder

相關問題