代码之家  ›  专栏  ›  技术社区  ›  jerjer

在jtree中排列节点

  •  4
  • jerjer  · 技术社区  · 15 年前

    我有一个jtree,用户可以在其中拖放或重新排列节点, 保存后,我必须重新排列节点,以便文件类型节点必须出现 文件夹类型节点之前。我不需要对文件/文件夹名进行排序。

    User Tree:

     -FolderA
       +FFA1
       -FA1
       -FA2
     -FolderB
       -FB1
     -File1
     -File2
     +FolderC
     -File3
    

    结果树:

    -File1
     -File2
     -File3
     -FolderA   
       -FA1
       -FA2
       +FAF1
     -FolderB
       -FB1
     +FolderC
    

    我有下面的代码,它是有效的,但我不知道这是正确的方式或良好的做法也许。 你能提出两种解决方案中哪一种更好,或者你能提出其他的建议吗?

    非常感谢。

    解决方案1:

    private void arrange(DefaultMutableTreeNode parent){
        DefaultMutableTreeNode sorted = new DefaultMutableTreeNode();
        List<DefaultMutableTreeNode> files = new ArrayList<DefaultMutableTreeNode>();
        List<DefaultMutableTreeNode> folders = new ArrayList<DefaultMutableTreeNode>();
    
        for (int i = 0; i < parent.getChildCount(); i++){
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent.getChildAt(i);
            int type = ((BusinessObject) node.getUserObject()).getType();
            if (type == BusinessObject.FILE)
                files.add(node);
            else{
                arrange(node);
                folders.add(node);
            }
        }
        for (int i = 0; i < files.size(); i++)
            sorted.add((DefaultMutableTreeNode) files.get(i));
    
        for (int i = 0; i < folders.size(); i++)
            sorted.add((DefaultMutableTreeNode) folders.get(i));
    
        while (sorted.getChildCount() > 0)
            parent.add((DefaultMutableTreeNode) sorted.getChildAt(0));
    
        sorted = null;
        files = null;
        folders = null;
    }
    

    解决方案2:

    private void arrange(DefaultMutableTreeNode parent){
        DefaultMutableTreeNode sorted = new DefaultMutableTreeNode();
        List<DefaultMutableTreeNode> nodes = new ArrayList<DefaultMutableTreeNode>();
    
        for (int i = 0; i < parent.getChildCount(); i++){
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent.getChildAt(i);
            int type = ((BusinessObject) node.getUserObject()).getType();
            if (type == BusinessObject.FILE)
                nodes.add(node);
        }
    
        for (int i = 0; i < parent.getChildCount(); i++){
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) parent.getChildAt(i);
            int type = ((BusinessObject) node.getUserObject()).getType();
            if (type == BusinessObject.FOLDER){
                arrange(node);
                nodes.add(node);
            }
        }
    
        for (int i = 0; i < nodes.size(); i++)
            sorted.add((DefaultMutableTreeNode) nodes.get(i));
    
        while (sorted.getChildCount() > 0)
            parent.add((DefaultMutableTreeNode) sorted.getChildAt(0));
    
        sorted = null;
        nodes = null;
    }
    
    5 回复  |  直到 8 年前
        1
  •  3
  •   Jeremy Stein    15 年前

    我认为两者都是很好的解决方案。很容易知道他们在做什么:拉出文件,拉出文件夹,按正确的顺序把它们扔回到树上。而且,递归调用是直接和直观的。

    选择你觉得最自然的。第二个看起来更像我的方式,但那只是我,没有太大的区别。

    你使用Java 5还是6?如果是,使用 for-each loops .另外,您不必在方法的末尾清除私有变量的值。不管怎样,当方法返回时,它们都会消失。

        2
  •  3
  •   Mike    14 年前

    这实际上和我在应用程序中使用它时一样有效。我的节点都是默认的可变树节点,没有任何更改。 将传入并更改要排序的节点。 它生成子节点的数组列表。然后是节点文本的两个数组列表,其中一个被排序。另一个用于查找数组列表中的节点。 所有节点都从初始节点移出,然后从数组列表中重新添加。 工作有魅力,可能是过度使用阵列,但我喜欢他们。

    private void sortchildren(DefaultMutableTreeNode node) {
            ArrayList children = Collections.list(node.children());
            // for getting original location
            ArrayList<String> orgCnames = new ArrayList<String>();
            // new location
            ArrayList<String> cNames = new ArrayList<String>();
            //move the child to here so we can move them back
            DefaultMutableTreeNode temParent = new DefaultMutableTreeNode();
            for(Object child:children) {
                DefaultMutableTreeNode ch = (DefaultMutableTreeNode)child;
                temParent.insert(ch,0);
                cNames.add(ch.toString().toUpperCase());
                orgCnames.add(ch.toString().toUpperCase());
            }
            Collections.sort(cNames);
            for(String name:cNames) {
                // find the original location to get from children arrayList
                int indx = orgCnames.indexOf(name);
                node.insert((DefaultMutableTreeNode)children.get(indx),node.getChildCount());
            }
        }
    
        3
  •  1
  •   shinds    12 年前

    我对Mike的代码示例做了一些修改,以考虑重复的名称,并在文件之前对文件夹进行排序。否则它会像做梦一样工作。谢谢迈克。

    public static void sortTreeNode(DefaultMutableTreeNode node) {
    List<DefaultMutableTreeNode> children = Collections.list(node.children());
    List<String> sortFileNames = new ArrayList<>();
    List<String> sortFolderNames = new ArrayList<>();
    List<String> sortNames = new ArrayList<>();
    List<String> origNames = new ArrayList<>();
    DefaultMutableTreeNode temParent = new DefaultMutableTreeNode();
    for (int x = 0; x < children.size(); x++) {
        DefaultMutableTreeNode child = children.get(x);
        temParent.insert(child, 0);
        if (!child.isLeaf()) {
        sortFolderNames.add(ViewMethods.getStringForNode(child).toUpperCase() + x);
        origNames.add(ViewMethods.getStringForNode(child).toUpperCase() + x);
        if (child.getChildCount() > 0) {
            sortTreeNode(child);
        }
        } else {
        sortFileNames.add(ViewMethods.getStringForNode(child).toUpperCase() + x);
        origNames.add(ViewMethods.getStringForNode(child).toUpperCase() + x);
        }
    }
    Collections.sort(sortFolderNames);
    Collections.sort(sortFileNames);
    sortNames.addAll(sortFolderNames);
    sortNames.addAll(sortFileNames);
    for (String name : sortNames) {
        // find the original location to get from children arrayList
        int indx = origNames.indexOf(name);
        node.insert(children.get(indx), node.getChildCount());
    }
    }
    
        4
  •  1
  •   Miguel RS    8 年前

    现在,Java 8更容易:

    DefaultMutableTreeNode node; // node can't be null, it's an example
    
    List<DefaultMutableTreeNode> childrenList = Collections.list(node.children());
    
    Collections.sort(childrenList, (o1,o2) ->
    ((Node) o1.getUserObject()).getName().compareToIgnoreCase(((Node)o2.getUserObject()).getName()));
    
    node.removeAllChildren();
    childrenList.forEach(node::add);
    
        5
  •  0
  •   oussama    12 年前

    它非常简单: 将文件夹的所有叶放入一个数组(名为hear o_people)

        DefaultMutableTreeNode all_node = 
         new DefaultMutableTreeNode("Root folder");
        DefaultMutableTreeNode one_node;
        Vector sorted_people=new Vector();
        // a simple algorithm of sorting array
        for (int i=0;i&lt;o_people.length-1;i++){
        for (int j=i+1;j&lt;o_people.length;j++){
            if(o_people[j].toString().compareTo
               (o_people[i].toString())<0) {
    
                String permut=o_people[i].toString();
                o_people[i]=o_people[j];
                o_people[j]=permut;
    
            }
    
        }
        sorted_people.add(o_people[i]);
    
       //in my case the leaf is a JChechbox but you can put a String
        one_node = new DefaultMutableTreeNode
         ( new JCheckBox(o_people[i].toString(), boolien));
        all_node.add(one_node);
        }
    
        tree_model.setRoot(all_node);
    

    简单!!!不是吗?