2016-12-29 3 views
0

Рассмотрим следующий код:JTree перетащить на панель в качестве объекта

import java.awt.BorderLayout; 
import java.awt.Container; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.io.IOException; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTree; 
import javax.swing.TransferHandler; 
import javax.swing.TransferHandler.TransferSupport; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreeModel; 

class Element { 
    String s; 
    public Element(String s) { 
    this.s = s; 
    } 
} 

public class DnDTest { 
    public static void main(String args[]) { 
    JFrame f = new JFrame("Test"); 
    f.setSize(640, 400); 
    Container c = f.getContentPane(); 
    c.setLayout(new BorderLayout()); 
    JTree t = new JTree(); 
    t.setDragEnabled(true); 
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Element("root")); 
    root.add(new DefaultMutableTreeNode(new Element("child"))); 
    t.setModel(new DefaultTreeModel(root)); 
    c.add(t, BorderLayout.WEST); 
    JPanel p = new JPanel(); 
    c.add(p, BorderLayout.CENTER); 
    p.setTransferHandler(new TransferHandler("entity") { 
     @Override 
     public boolean canImport(TransferSupport support) { 
     return true; 
     } 
     @Override 
     public boolean importData(TransferHandler.TransferSupport support) { 
     Transferable t = support.getTransferable(); 
     DataFlavor[] fv = t.getTransferDataFlavors(); 
     Object o; 
     try { 
      for (DataFlavor f: fv) { 
      o = t.getTransferData(f); 
      System.out.println(f + " => " + o.getClass().getName()+", " + o); 
      } 
     } catch (UnsupportedFlavorException | IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return false; 
     } 
    }); 
    f.setVisible(true); 
    } 
} 

Когда я перетащить узел из дерева на правой панели, это печатает следующий вывод:

java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.lang.String] => java.lang.String, <html> 
<body> 
<ul> 
    <li>[email protected] 
</ul> 
</body> 
</html> 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.Reader] => java.io.StringReader, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=unicode] => java.io.ByteArrayInputStream, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.lang.String] => java.lang.String, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.Reader] => java.io.StringReader, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=unicode] => java.io.ByteArrayInputStream, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-jvm-local-objectref;representationclass=java.lang.String] => java.lang.String, [email protected] 
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=java.lang.String] => java.lang.String, [email protected] 

So , вне зависимости от того, что DataFlavor Я использую, результат всегда String. Что мне нужно изменить, чтобы получить ссылку на экземпляр Element, связанный как объект пользователя с узлом дерева?

ответ

0

Я сделал еще несколько копаний и нашел решение. Проводка для справки:

import java.awt.BorderLayout; 
import java.awt.Container; 
import java.awt.datatransfer.Clipboard; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.awt.event.InputEvent; 
import java.io.IOException; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTree; 
import javax.swing.TransferHandler; 
import javax.swing.TransferHandler.TransferSupport; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreeModel; 
import javax.swing.tree.TreeNode; 
import javax.swing.tree.TreePath; 

class Element { 
    private String id; 
    public Element(String id) { 
    this.id = id;  
    } 

    public String toString() { 
    return "A"; 
    } 

    public String getId() { 
    return id; 
    } 
} 

class CustomTransferHandler extends TransferHandler { 
    @Override 
    protected Transferable createTransferable(JComponent c) { 
    JTree tree = (JTree)c; 
    TreePath[] paths = tree.getSelectionPaths(); 
    Transferable t = null; 
     DataFlavor DF = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType, Element.class.getName()); 
     t = new Transferable() { 

     @Override 
     public DataFlavor[] getTransferDataFlavors() { 
      return new DataFlavor[]{DF}; 
     } 

     @Override 
     public boolean isDataFlavorSupported(DataFlavor flavor) { 
      return flavor.equals(DF); 
     } 

     @Override 
     public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 
      if (!flavor.equals(DF)) { 
      return null; 
      } 
      Element[] els = new Element[paths.length]; 
      int idx = 0; 
      for (TreePath path : paths) { 
      Object el = path.getLastPathComponent(); 
      els[idx++] = (Element)((DefaultMutableTreeNode)el).getUserObject(); 
      } 
      return els; 
     }   
     }; 
    return t;   
    } 

    @Override 
    public int getSourceActions(JComponent c) { 
    return COPY; 
    } 
} 

public class DnDTest { 
    public static void main(String args[]) { 
    JFrame f = new JFrame("Test"); 
    f.setSize(640, 400); 
    Container c = f.getContentPane(); 
    c.setLayout(new BorderLayout()); 
    JTree t = new JTree(); 
    t.setTransferHandler(new CustomTransferHandler()); 

    t.setDragEnabled(true); 
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Element("root")); 
    root.add(new DefaultMutableTreeNode(new Element("child"))); 
    t.setModel(new DefaultTreeModel(root)); 
    c.add(t, BorderLayout.WEST); 
    JPanel p = new JPanel(); 
    c.add(p, BorderLayout.CENTER); 
    p.setTransferHandler(new TransferHandler("entity") { 
     @Override 
     public boolean canImport(TransferSupport support) { 
     return true; 
     } 
     @Override 
     public boolean importData(TransferHandler.TransferSupport support) { 
     Transferable t = support.getTransferable(); 
     DataFlavor[] fv = t.getTransferDataFlavors(); 
     Element[] els; 
     try { 
      for (DataFlavor f: fv) { 
      try { 
       els = (Element[])t.getTransferData(f); 
       for (Element el : els) { 
       System.out.println(el.getId()); 
       } 
      }catch(RuntimeException ex) { 
       ex.printStackTrace(); 
      } 
      } 
     } catch (UnsupportedFlavorException | IOException e) { 
      return false; 
     } 
     return true; 
     } 
    }); 
    f.setVisible(true); 
    } 
} 
Смежные вопросы