【发布时间】:2011-06-03 12:26:38
【问题描述】:
我的类结构如下:
DefaultMutableTreeNode |_ BCS结构 |_ |模块 |_ |部分 |_ 页Module、Section 和 Page 是我在 JTree 中实际使用的。如果您运行下面的示例代码,则拖放工作。注意它使用的是 DefaultMutableTreeNodes。但是,如果我将代码放在使用 DefualtMutableTreeNode 子类的真实应用程序中,它就不起作用。
在单步执行代码时,我注意到了两个感兴趣的领域。第一个是这样的:
class TreeTransferHandler extends TransferHandler {
DataFlavor nodesFlavor;
DataFlavor[] flavors = new DataFlavor[1];
DefaultMutableTreeNode[] nodesToRemove;
public TreeTransferHandler() {
try {
String mimeType = DataFlavor.javaJVMLocalObjectMimeType
+ ";class=\""
+ javax.swing.tree.DefaultMutableTreeNode[].class.getName()
+ "\"";
nodesFlavor = new DataFlavor(mimeType);
flavors[0] = nodesFlavor;
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFound: " + e.getMessage());
}
}
这是设置 DataFlavor 的地方。它将它设置为 DefualtMutableTreeNode 数组,我认为这是正确的,因为 DefaultMutableTreeNode 是我的节点的超类。但这是我认为问题所在的一个领域。
另一点是在调试这段代码时,我得到了:
public DataFlavor[] getTransferDataFlavors() {
return flavors;
}
在拖放失败之前。我假设它返回一个不太喜欢的 DataFlavor。这就是为什么我认为 DataFlavor 有问题的原因。我还需要做/修改什么才能使其与子类一起使用吗?有什么想法或建议吗?
谢谢!
完整的示例代码:
导入 java.awt.*; 导入 java.awt.datatransfer.*; 导入 java.awt.dnd.*; 导入 java.util.*; 导入 java.util.List; 导入 javax.swing.*; 导入 javax.swing.tree.*; 公共类 TreeDragAndDrop { 私人 JScrollPane getContent() { JTree 树 = 新 JTree(); tree.setDragEnabled(true); tree.setDropMode(DropMode.ON_OR_INSERT); tree.setTransferHandler(new TreeTransferHandler()); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); 展开树(树); 返回新的 JScrollPane(树); } 私人无效expandTree(JTree树){ DefaultMutableTreeNode 根 = (DefaultMutableTreeNode)tree.getModel().getRoot(); 枚举 e = root.breadthFirstEnumeration(); 而(e.hasMoreElements()){ DefaultMutableTreeNode 节点 = (DefaultMutableTreeNode)e.nextElement(); 如果(node.isLeaf())继续; int row = tree.getRowForPath(new TreePath(node.getPath())); 树.expandRow(行); } } 公共静态无效主要(字符串[]参数){ JFrame f = 新的 JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new TreeDragAndDrop().getContent()); f.setSize(400,400); f.setLocation(200,200); f.setVisible(true); } } 类 TreeTransferHandler 扩展 TransferHandler { 数据风味节点风味; DataFlavor[] 口味 = 新 DataFlavor[1]; DefaultMutableTreeNode[] nodesToRemove; 公共 TreeTransferHandler() { 尝试 { 字符串 mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=\"" + javax.swing.tree.DefaultMutableTreeNode[].class.getName() + "\""; 节点风味=新数据风味(mimeType); 风味[0] = 节点风味; } 捕捉(ClassNotFoundException e){ System.out.println("ClassNotFound:" + e.getMessage()); } } 公共布尔canImport(TransferHandler.TransferSupport支持){ if(!support.isDrop()) { 返回假; } support.setShowDropLocation(true); if(!support.isDataFlavorSupported(nodesFlavor)) { 返回假; } // 不允许拖放源选择。 JTree.DropLocation dl = (JTree.DropLocation)support.getDropLocation(); JTree 树 = (JTree)support.getComponent(); int dropRow = tree.getRowForPath(dl.getPath()); int[] selRows = tree.getSelectionRows(); for(int i = 0; i 0 && 目标.getLevel() 0 && selRows.length == 1) 返回假; // 首先可能有孩子。 for(int i = 1; i selRows.length-1) { // 并非 first 的所有子项都被选中。 返回假; } } } 返回真; } protected Transferable createTransferable(JComponent c) { JTree 树 = (JTree)c; TreePath[] 路径 = tree.getSelectionPaths(); 如果(路径!= null){ // 组成一个节点数组用于传输和 // 另一个 for/of 将被删除的节点 // 成功删除后的 exportDone。 列出副本 = 新的 ArrayList(); 删除列表 = 新的 ArrayList(); DefaultMutableTreeNode 节点 = (DefaultMutableTreeNode)paths[0].getLastPathComponent(); DefaultMutableTreeNode 复制 = 复制(节点); 副本。添加(复制); toRemove.add(节点); for(int i = 1; i node.getLevel()) { // 子节点 复制。添加(复制(下一个)); // 节点已经包含子节点 } else { // 兄弟 副本。添加(副本(下一个)); toRemove.add(下一个); } } DefaultMutableTreeNode[] 节点 = copy.toArray(new DefaultMutableTreeNode[copies.size()]); 节点删除 = toRemove.toArray(new DefaultMutableTreeNode[toRemove.size()]); 返回新的 NodesTransferable(nodes); } 返回空值; } /** createTransferable 中使用的防御性副本。 */ 私有 DefaultMutableTreeNode 副本(TreeNode 节点){ 返回新的 DefaultMutableTreeNode(node); } protected void exportDone(JComponent source, Transferable data, int action) { 如果((动作和移动)==移动){ JTree 树 = (JTree) 源代码; DefaultTreeModel 模型 = (DefaultTreeModel)tree.getModel(); // 删除createTransferable中nodesToRemove中保存的节点。 for(int i = 0; 我【问题讨论】:
-
是否有错误信息或某种异常?你能扩展一下“不起作用”吗?
-
不,没有错误信息。它根本不允许进行拖放操作。如果您尝试拖放一个节点,它会正确调用函数,只是有一些设置不正确,无法让我的 JTree 接受我的子类是可拖放的。
-
您能否尝试在代码中使用 MySubDefaultMutableTreeNode 代替 String mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=\"" + javax.swing.tree.MySubDefaultMutableTreeNode[].class.getName() + " \"";
-
您提供给我们的代码不完整,请更新问题。
-
@tulskiy 完整的代码在那里,但它被我在 for 循环中的
标签: java swing jtree drag-and-drop