Java JTree Expand makeTreeAutoExpandable(JTree tree)

Here you can find the source of makeTreeAutoExpandable(JTree tree)

Description

By calling this method, the provided tree will become auto-expandable, i.e.

License

Open Source License

Parameter

Parameter Description
tree The tree to make auto-expandable

Declaration

public static void makeTreeAutoExpandable(JTree tree) 

Method Source Code

//package com.java2s;
/*//from w  w w.  ja  v a2s.  com
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
 * Other names may be trademarks of their respective owners.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */

import javax.swing.*;

import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;

import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

public class Main {
    public static final String PROP_AUTO_EXPANDING = "auto_expanding";
    public static final String PROP_EXPANSION_TRANSACTION = "expansion_transaction";
    private static final int MAX_TREE_AUTOEXPAND_LINES = 50;

    /** By calling this method, the provided tree will become auto-expandable, i.e.
     * When a node is expanded, if it has only one child, that child gets expanded, and so on.
     * This is very useful for trees that have a deep node hierarchy with typical paths from
     * root to leaves containing only one node along the whole path.
     *
     * @param tree The tree to make auto-expandable
     */
    public static void makeTreeAutoExpandable(JTree tree) {
        makeTreeAutoExpandable(tree, 1, false);
    }

    public static void makeTreeAutoExpandable(JTree tree, final boolean dontExpandToLeafs) {
        makeTreeAutoExpandable(tree, 1, dontExpandToLeafs);
    }

    /** By calling this method, the provided tree will become auto-expandable, i.e.
     * When a node is expanded, if it has only one child, that child gets expanded, and so on.
     * This is very useful for trees that have a deep node hierarchy with typical paths from
     * root to leaves containing only one node along the whole path.
     *
     * @param tree The tree to make auto-expandable
     */
    public static void makeTreeAutoExpandable(JTree tree, final int maxChildToExpand) {
        makeTreeAutoExpandable(tree, maxChildToExpand, false);
    }

    public static void makeTreeAutoExpandable(final JTree tree, final int maxChildToExpand,
            final boolean dontExpandToLeafs) {
        tree.addTreeExpansionListener(new TreeExpansionListener() {
            boolean internalChange = false;

            public void treeCollapsed(TreeExpansionEvent event) {
            }

            public void treeExpanded(TreeExpansionEvent event) {
                if (internalChange || Boolean.TRUE.equals(tree.getClientProperty(PROP_EXPANSION_TRANSACTION))) { // NOI18N
                    return;
                }

                // Auto expand more if the just expanded child has only one child
                TreePath path = event.getPath();
                JTree tree = (JTree) event.getSource();
                internalChange = true;
                tree.putClientProperty(PROP_AUTO_EXPANDING, Boolean.TRUE);
                try {
                    autoExpand(tree, path, MAX_TREE_AUTOEXPAND_LINES, maxChildToExpand, dontExpandToLeafs);
                } finally {
                    tree.putClientProperty(PROP_AUTO_EXPANDING, null);
                    internalChange = false;
                }
            }
        });
    }

    /** Checks give TreePath for the last node, and if it ends with a node with just one child,
     * it keeps expanding further.
     * Current implementation expands through the first child that is not leaf. To more correctly
     * fulfil expected semantics in case maxChildToExpand is > 1, it should expand all paths through
     * all children.
     *
     * @param tree
     * @param path
     * @param maxChildToExpand
     */
    public static void autoExpand(JTree tree, TreePath path, int maxLines, int maxChildToExpand,
            boolean dontExpandToLeafs) {
        TreeModel model = tree.getModel();
        Object node = path.getLastPathComponent();
        TreePath newPath = path;

        int currentLines = 0;

        while (currentLines++ < maxLines && !model.isLeaf(node) && (model.getChildCount(node) > 0)
                && (model.getChildCount(node) <= maxChildToExpand)) {
            for (int i = 0; i < model.getChildCount(node); i++) {
                node = tree.getModel().getChild(node, i);

                if (!model.isLeaf(node)) {
                    if (dontExpandToLeafs && hasOnlyLeafs(tree, node)) {
                        break;
                    }

                    newPath = newPath.pathByAddingChild(node); // if the leaf is added the path will not expand

                    break; // from for
                }
            }
        }

        tree.expandPath(newPath);
    }

    public static boolean hasOnlyLeafs(JTree tree, Object node) {
        TreeModel model = tree.getModel();

        for (int i = 0; i < model.getChildCount(node); i++) {
            if (!model.isLeaf(model.getChild(node, i))) {
                return false;
            }
        }

        return true;
    }
}

Related

  1. getExpandedPaths(JTree tree)
  2. getLastExpandedNodes(final JTree tree)
  3. getPaths(JTree tree, boolean expanded)
  4. getTreeSelectedExpandedIcon()
  5. isTreePathExpandable(TreeModel treeModel, TreePath treePath)
  6. searchUnexpandedPath(JTree tree, TreePath path, int index, TreeNode node, TreePath[] result, boolean compareOnlyLabels)
  7. setExpandedIcon(JTree tree, Icon icon)
  8. setExpandedOnEdt(JTree tree, TreePath path, boolean expanded)
  9. setExpandedPaths(JTree tree, TreePath[] expandedPaths)