如何使用树木

使用JTree类,可以显示分层数据。 JTree对象实际上并不包含您的数据。它只是提供了数据视图。像任何非平凡的 Swing 组件一样,树通过查询其数据模型来获取数据。这是一棵树的图片:

A tree

如上图所示,JTree垂直显示其数据。树显示的每一行仅包含一项数据,称为* node 。每棵树都有一个 root 节点,所有节点都从该节点下降。默认情况下,树显示根节点,但您可以另外决定。节点可以有子节点,也可以没有子节点。我们将可以有子节点的节点(无论它们当前是否“有”子节点)称为“分支”节点。不能有子节点的节点是叶子*节点。

分支节点可以具有任意数量的子代。通常,用户可以通过单击分支节点来展开和折叠分支节点,从而使子节点可见或不可见。默认情况下,除根节点外的所有分支节点都开始折叠。程序可以通过侦听树扩展或树将扩展事件来检测分支节点扩展状态的变化,如如何编写树扩展侦听器如何编写一个树状扩展侦听器中所述。

树中的特定节点可以通过 TreePath(封装一个节点及其所有祖先的对象)或显示行(在显示区域中的每一行显示一个节点)来标识。

  • 展开节点是非叶子节点,当其所有祖先都展开时将显示其子节点。

  • 折叠的节点是隐藏它们的节点。

  • 隐藏节点是处于崩溃前辈之下的节点。

本节的其余部分讨论以下主题:

创建树

这是一个应用程序的图片,其上半部分在滚动窗格中显示一棵树。

TreeDemo

Try this:

  • 单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 Tree Demo。另外,要自己编译和运行示例,请查阅example index

  • 展开一个或多个节点。
    您可以通过单击项目左侧的圆圈来执行此操作。

  • 折叠节点。
    通过单击扩展节点左侧的圆圈来执行此操作。

以下代码取自TreeDemo.java,创建了JTree对象并将其放在滚动窗格中:

//Where instance variables are declared:
private JTree tree;
...
public TreeDemo() {
    ...
    DefaultMutableTreeNode top =
        new DefaultMutableTreeNode("The Java Series");
    createNodes(top);
    tree = new JTree(top);
    ...
    JScrollPane treeView = new JScrollPane(tree);
    ...
}

该代码创建一个DefaultMutableTreeNode的实例作为树的根节点。然后,它在树中创建其余节点。之后,它将创建树,并指定根节点作为JTree构造函数的参数。最后,它将树放在滚动窗格中,这是一种常见的策略,因为要显示完整的展开树,否则将需要太多空间。

以下是在根节点下创建节点的代码:

private void createNodes(DefaultMutableTreeNode top) {
    DefaultMutableTreeNode category = null;
    DefaultMutableTreeNode book = null;
    
    category = new DefaultMutableTreeNode("Books for Java Programmers");
    top.add(category);
    
    //original Tutorial
    book = new DefaultMutableTreeNode(new BookInfo
        ("The Java Tutorial: A Short Course on the Basics",
        "tutorial.html"));
    category.add(book);
    
    //Tutorial Continued
    book = new DefaultMutableTreeNode(new BookInfo
        ("The Java Tutorial Continued: The Rest of the JDK",
        "tutorialcont.html"));
    category.add(book);
    
    //Swing Tutorial
    book = new DefaultMutableTreeNode(new BookInfo
        ("The Swing Tutorial: A Guide to Constructing GUIs",
        "swingtutorial.html"));
    category.add(book);

    //...add more books for programmers...

    category = new DefaultMutableTreeNode("Books for Java Implementers");
    top.add(category);

    //VM
    book = new DefaultMutableTreeNode(new BookInfo
        ("The Java Virtual Machine Specification",
         "vm.html"));
    category.add(book);

    //Language Spec
    book = new DefaultMutableTreeNode(new BookInfo
        ("The Java Language Specification",
         "jls.html"));
    category.add(book);
}

DefaultMutableTreeNode构造函数的参数是* user object *,它是一个包含或指向与树节点关联的数据的对象。用户对象可以是字符串,也可以是自定义对象。如果实现自定义对象,则应实现其toString方法,以便它返回要为该节点显示的字符串。默认情况下,JTree 使用从 toString 返回的值来呈现每个节点,因此toString返回有意义的值很重要。有时,覆盖toString是不可行的;在这种情况下,您可以重写 JTree 的 convertValueToText 以将模型中的对象 Map 到要显示的字符串 中。

例如,上一代码段中使用的BookInfo类是一个自定义类,其中包含两段数据:一本书的名称和描述该书的 HTML 文件的 URL。实现toString方法以返回书名。因此,与BookInfo对象关联的每个节点都显示书名。

Note:

您可以通过在树节点中的字符串 中放置 HTML 标记来指定文本格式。有关详情,请参见在 Swing 组件中使用 HTML

总而言之,您可以通过调用JTree构造函数并指定将 TreeNode 作为参数实现的类来创建树。您可能应该将树放置在滚动窗格中,以便树不会占用太多空间。您无需执行任何操作即可使树节点响应用户单击而展开和折叠。但是,您确实必须添加一些代码以使树在用户选择节点时做出响应-例如,通过单击节点。

响应节点选择

响应树节点选择很简单。您实现一个树选择侦听器并将其注册在树上。以下代码显示了TreeDemo程序中与选择相关的代码:

//Where the tree is initialized:
    tree.getSelectionModel().setSelectionMode
            (TreeSelectionModel.SINGLE_TREE_SELECTION);

    //Listen for when the selection changes.
    tree.addTreeSelectionListener(this);
...
public void valueChanged(TreeSelectionEvent e) {
//Returns the last path element of the selection.
//This method is useful only when the selection model allows a single selection.
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)
                       tree.getLastSelectedPathComponent();

    if (node == null)
    //Nothing is selected.     
    return;

    Object nodeInfo = node.getUserObject();
    if (node.isLeaf()) {
        BookInfo book = (BookInfo)nodeInfo;
        displayURL(book.bookURL);
    } else {
        displayURL(helpURL); 
    }
}

前面的代码执行以下任务:

  • 获取树的默认TreeSelectionModel,然后对其进行设置,以便一次最多选择一个树节点。

  • 在树上注册事件处理程序。事件处理程序是一个实现TreeSelectionListenerinterface的对象。

  • 在事件处理程序中,通过调用树的getLastSelectedPathComponent方法来确定选择哪个节点。

  • 使用getUserObject方法获取与节点关联的数据。

有关处理树选择事件的更多详细信息,请参见如何编写树选择侦听器

自定义树的显示

这是由 Java,Windows 和 Mac OS 外观实现绘制的一些树节点的图片。

带有斜线的 TreeDemoWindows 外观中的一棵树MacOS 外观中的一棵树
Java 外观Windows 外观Mac OS 外观

如前面的图所示,树通常为每个节点显示一个图标和一些文本。您可以自定义这些内容,我们将在稍后显示。

一棵树通常还会执行一些特定于外观的绘画,以指示节点之间的关系。您可以通过有限的方式自定义这幅画。首先,您可以使用tree.setRootVisible(true)显示根节点,或使用tree.setRootVisible(false)隐藏根节点。其次,您可以使用tree.setShowsRootHandles(true)来请求一棵树的顶级节点(根节点(如果可见)或其子节点(如果不可见))具有使它们能够扩展或折叠的句柄。

如果使用 Java 外观,则可以自定义是否绘制线条以显示树节点之间的关系。默认情况下,Java 外观在节点之间绘制倾斜的线条。通过设置树的JTree.lineStyleClient 端属性,可以指定其他约定。例如,要请求 Java 外观仅使用水平线对节点进行分组,请使用以下代码:

tree.putClientProperty("JTree.lineStyle", "Horizontal");

要指定 Java 外观不应画线,请使用以下代码:

tree.putClientProperty("JTree.lineStyle", "None");

以下快照显示了使用 Java 外观时设置JTree.lineStyle属性的结果。

带有斜线的 TreeDemo带有水平线的 TreeDemo没有行的 TreeDemo
"Angled"(默认)"Horizontal""None"

无论外观如何,节点显示的默认图标都取决于该节点是否为叶子,如果不是,则取决于它是否展开。例如,在 Windows 和 Motif 外观实现中,每个叶节点的默认图标是一个点。在 Java 外观中,默认的叶子图标是纸状符号。在我们展示的所有外观实现中,分支节点都用类似于文件夹的符号标记。对于扩展分支和收缩分支,某些外观可能具有不同的图标。

您可以轻松更改用于叶节点,扩展分支节点或折叠分支节点的默认图标。为此,您首先创建一个DefaultTreeCellRenderer的实例。您始终可以从头开始创建自己的 TreeCellRenderer 实现,从而重新使用所需的任何组件。接下来,通过在渲染器上调用以下一种或多种方法来指定要使用的图标:setLeafIcon(对于叶节点),setOpenIcon(对于扩展分支节点),setClosedIcon(对于折叠的分支节点)。如果您希望树不显示某种类型的节点的图标,请为该图标指定null。设置完图标后,请使用树的setCellRenderer方法指定DefaultTreeCellRenderer绘制其节点。这是取自TreeIconDemo.java的示例:

ImageIcon leafIcon = createImageIcon("images/middle.gif");
if (leafIcon != null) {
    DefaultTreeCellRenderer renderer = 
        new DefaultTreeCellRenderer();
    renderer.setLeafIcon(leafIcon);
    tree.setCellRenderer(renderer);
}

这是 TreeIconDemo 的屏幕截图:

TreeIconDemo

Try this:

如果要更好地控制节点图标或要提供工具提示,可以通过创建DefaultTreeCellRenderer的子类并覆盖getTreeCellRendererComponent方法来实现。由于DefaultTreeCellRendererJLabel的子类,因此可以使用任何JLabel方法(例如setIcon)来自定义DefaultTreeCellRenderer

以下来自TreeIconDemo2.java的代码创建了一个单元格渲染器,该渲染器根据节点文本数据中是否包含“ Tutorial”一词来改变叶子图标。渲染器还指定工具提示文本,如粗线所示。

Try this:

//...where the tree is initialized:
    //Enable tool tips.
    ToolTipManager.sharedInstance().registerComponent(tree);
    
    ImageIcon tutorialIcon = createImageIcon("images/middle.gif");
    if (tutorialIcon != null) {
        tree.setCellRenderer(new MyRenderer(tutorialIcon));
    }
...
class MyRenderer extends DefaultTreeCellRenderer {
    Icon tutorialIcon;

    public MyRenderer(Icon icon) {
        tutorialIcon = icon;
    }

    public Component getTreeCellRendererComponent(
                        JTree tree,
                        Object value,
                        boolean sel,
                        boolean expanded,
                        boolean leaf,
                        int row,
                        boolean hasFocus) {

        super.getTreeCellRendererComponent(
                        tree, value, sel,
                        expanded, leaf, row,
                        hasFocus);
        if (leaf && isTutorialBook(value)) {
            setIcon(tutorialIcon);
            setToolTipText("This book is in the Tutorial series.");
        } else {
            setToolTipText(null); //no tool tip
        } 

        return this;
    }

    protected boolean isTutorialBook(Object value) {
        DefaultMutableTreeNode node =
                (DefaultMutableTreeNode)value;
        BookInfo nodeInfo =
                (BookInfo)(node.getUserObject());
        String title = nodeInfo.bookName;
        if (title.indexOf("Tutorial") >= 0) {
            return true;
        }

        return false;
    }
}

结果如下:

TreeIconDemo2

您可能想知道单元格渲染器如何工作。当一棵树绘制每个节点时,JTree及其特定于外观的实现都实际上不包含绘制该节点的代码。相反,树使用单元渲染器的绘制代码来绘制节点。例如,要绘制具有字符串“ Java 编程语言”的叶节点,树将要求其单元格渲染器返回一个可以使用该字符串 绘制叶节点的组件。如果单元格渲染器是DefaultTreeCellRenderer,则它将返回一个标签,该标签绘制默认的叶子图标,后跟字符串。

单元格渲染器仅绘制;它无法处理事件。如果要将事件处理添加到树,则需要在树上注册处理程序,或者如果仅在选择节点时才进行处理,则需要树的* cell editor *。有关单元格编辑器的信息,请参见概念:编辑器和渲染器。该部分讨论表单元格编辑器和渲染器,它们类似于树单元格编辑器和渲染器。

动态更改树

下图显示了一个名为 DynamicTreeDemo 的应用程序,它使您可以向可见树中添加节点或从中删除节点。您也可以在每个节点中编辑文本。

DynamicTreeDemo

该应用程序基于教程 ReaderRichard Stanford 提供的示例。

Try this:

这是初始化树的代码:

rootNode = new DefaultMutableTreeNode("Root Node");
treeModel = new DefaultTreeModel(rootNode);
treeModel.addTreeModelListener(new MyTreeModelListener());

tree = new JTree(treeModel);
tree.setEditable(true);
tree.getSelectionModel().setSelectionMode
        (TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);

通过显式创建树的模型,代码可以确保树的模型是DefaultTreeModel的实例。这样,我们知道树模型支持的所有方法。例如,我们知道我们可以调用模型的insertNodeInto方法,即使TreeModelinterface不需要该方法也是如此。

为了使树的节点中的文本可编辑,我们在树上调用setEditable(true)。当用户完成节点的编辑后,模型将生成一个树模型事件,该事件告诉所有侦听器(包括JTree)树节点已更改。请注意,尽管DefaultMutableTreeNode具有更改节点内容的方法,但更改应通过DefaultTreeModel cover 方法进行。否则,将不会生成树模型事件,并且树之类的侦听器将不知道更新。

要通知节点更改,我们可以实现TreeModelListener。这是一个树模型侦听器的示例,它可以检测用户何时 Importing 树节点的新名称:

class MyTreeModelListener implements TreeModelListener {
    public void treeNodesChanged(TreeModelEvent e) {
        DefaultMutableTreeNode node;
        node = (DefaultMutableTreeNode)
                 (e.getTreePath().getLastPathComponent());

        /*
         * If the event lists children, then the changed
         * node is the child of the node we have already
         * gotten.  Otherwise, the changed node and the
         * specified node are the same.
         */
        try {
            int index = e.getChildIndices()[0];
            node = (DefaultMutableTreeNode)
                   (node.getChildAt(index));
        } catch (NullPointerException exc) {}

        System.out.println("The user has finished editing the node.");
        System.out.println("New value: " + node.getUserObject());
    }
    public void treeNodesInserted(TreeModelEvent e) {
    }
    public void treeNodesRemoved(TreeModelEvent e) {
    }
    public void treeStructureChanged(TreeModelEvent e) {
    }
}

这是 Add 按钮的事件处理程序用来向树中添加新节点的代码:

treePanel.addObject("New Node " + newNodeSuffix++);
...
public DefaultMutableTreeNode addObject(Object child) {
    DefaultMutableTreeNode parentNode = null;
    TreePath parentPath = tree.getSelectionPath();

    if (parentPath == null) {
        //There is no selection. Default to the root node.
        parentNode = rootNode;
    } else {
        parentNode = (DefaultMutableTreeNode)
                     (parentPath.getLastPathComponent());
    }

    return addObject(parentNode, child, true);
}
...
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                        Object child,
                                        boolean shouldBeVisible) {
    DefaultMutableTreeNode childNode =
            new DefaultMutableTreeNode(child);
    ...
    treeModel.insertNodeInto(childNode, parent,
                             parent.getChildCount());

    //Make sure the user can see the lovely new node.
    if (shouldBeVisible) {
        tree.scrollPathToVisible(new TreePath(childNode.getPath()));
    }
    return childNode;
}

该代码创建一个节点,将其插入到树模型中,然后在适当时请求扩展它上面的节点,并滚动树以使新节点可见。要将节点插入模型中,代码使用DefaultTreeModel类提供的insertNodeInto方法。

创建数据模型

如果DefaultTreeModel不符合您的需求,则需要编写一个自定义数据模型。您的数据模型必须实现TreeModelinterface。 TreeModel指定用于获取树的特定节点,获取特定节点的子代数,确定节点是否为叶,向模型通知树中的更改以及添加和删除树模型侦听器的方法。

有趣的是,TreeModelinterface接受任何类型的对象作为树节点。它不需要节点由DefaultMutableTreeNode对象表示,甚至不需要节点实现TreeNodeinterface。因此,如果TreeNodeinterface不适合您的树模型,请随意为树节点设计自己的表示形式。例如,如果您具有预先存在的分层数据结构,则无需复制它或将其强制插入TreeNode模具中。您只需要实现树模型,以便它使用现有数据结构中的信息。

下图显示了一个名为 GenealogyExample 的应用程序,该应用程序显示特定人的后代或祖先。 (感谢教程 ReaderOlivier Berlanger 提供了此示例.)

Try this:

GenealogyExample

您可以在GenealogyModel.java中找到自定义树模型实现。因为模型是作为Object子类而不是DefaultTreeModel的子类实现的,所以它必须直接实现TreeModelinterface。这需要实现用于获取有关节点的信息的方法,例如,哪个是根以及特定节点的子代是什么。在GenealogyModel的情况下,每个节点都由Person类型的对象表示,该对象不是TreeNode的自定义类。

树模型还必须实现添加和删除树模型侦听器的方法,并且当树的结构或数据发生更改时,必须向这些侦听器触发TreeModelEvent。例如,当用户指示 GenealogyExample 从显示祖先切换为显示后代时,树模型进行更改,然后触发事件以通知其侦听器(例如树组件)。

如何懒惰地装载孩子

当类的实际加载和实例化被延迟到实际使用该实例之前的时间点时,延迟加载是应用程序的 Feature。

懒惰地加载它们会获得任何收益吗?是的,这肯定会增加应用程序的性能。通过延迟加载,可以将内存资源专用于仅在实际使用对象时加载和实例化该对象。您还可以加快应用程序的初始加载时间。

延迟加载 Tree 子级的一种方法是利用 TreeWillExpandListener interface。例如,您可以声明并加载 Tree 的根,祖 parent 和父级以及应用程序,如以下代码所示:

让我们声明根,祖 parent 和 parent,如下所示:

class DemoArea extends JScrollPane
                   implements TreeWillExpandListener {
        .......
        .......

        private TreeNode createNodes() {
            DefaultMutableTreeNode root;
            DefaultMutableTreeNode grandparent;
            DefaultMutableTreeNode parent;

            root = new DefaultMutableTreeNode("San Francisco");

            grandparent = new DefaultMutableTreeNode("Potrero Hill");
            root.add(grandparent);

            parent = new DefaultMutableTreeNode("Restaurants");
            grandparent.add(parent);
            
            dummyParent = parent;
            return root;
        }

您可以将上面声明的节点加载到树中,如以下代码所示:

TreeNode rootNode = createNodes();
tree = new JTree(rootNode);
tree.addTreeExpansionListener(this);
tree.addTreeWillExpandListener(this);
.......
.......
setViewportView(tree);

现在,只要父节点Restaurants在应用程序中可见,就可以将子级延迟加载到应用程序。为此,让我们在一个单独的方法中声明两个子代,然后调用该方法,如以下代码所示:

private void LoadLazyChildren(){
            DefaultMutableTreeNode child;
            child = new DefaultMutableTreeNode("Thai Barbeque");
            dummyParent.add(child);
            child = new DefaultMutableTreeNode("Goat Hill Pizza");
            dummyParent.add(child);
            textArea.append(" Thai Barbeque and Goat Hill Pizza are loaded lazily");
        }

        .......
        .......

public void treeWillExpand(TreeExpansionEvent e) 
                    throws ExpandVetoException {
            saySomething("You are about to expand node ", e);
            int n = JOptionPane.showOptionDialog(
                this, willExpandText, willExpandTitle,
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                willExpandOptions,
                willExpandOptions[1]);
           
        LoadLazyChildren();
        }

请参阅如何编写一个树状扩展侦听器以获取 Tree-Will-Expand 侦听器的描述。

Tree API

树 API 相当广泛。下表仅列出了一些 API,主要介绍以下类别:

有关树 API 的更多信息,请参阅JTree的 API 文档以及tree package中的各种类和interface。另请参阅JComponent 类,以获取有关 API JTree继承自其超类的信息。

与树相关的类和interface

类或interfacePurpose
JTree向用户展示树的组件。
TreePath表示节点的路径。
TreeNode

MutableTreeNode
DefaultMutableTreeNode
缺省树模型期望其树节点要实现的interface,以及缺省树模型所使用的实现。
TreeModel
DefaultTreeModel
分别是树模型必须实现的interface和所使用的通常实现。
TreeCellRenderer
DefaultTreeCellRenderer
分别是树单元格渲染器必须实现的interface和所使用的通常实现。
TreeCellEditor
DefaultTreeCellEditor
分别是树单元格编辑器必须实现的interface和所使用的通常实现。
TreeSelectionModel
DefaultTreeSelectionModel
分别是树的选择模型必须实现的interface和所使用的通常实现。
TreeSelectionListener
TreeSelectionEvent
用于检测树选择更改的interface和事件类型。有关更多信息,请参见Getting Started
TreeModelListener
TreeModelEvent
用于检测树模型更改的interface和事件类型。有关更多信息,请参见如何编写树模型侦听器
TreeExpansionListener
TreeWillExpandListener
TreeExpansionEvent
用于检测树扩展和折叠的interface和事件类型。有关更多信息,请参见如何编写树扩展侦听器如何编写一个树状扩展侦听器
ExpandVetoExceptionTreeWillExpandListener可能抛出的异常,表示不应发生即将发生的扩展/崩溃。有关更多信息,请参见如何编写一个树状扩展侦听器

创建和设置树

构造函数或方法Purpose
JTree(TreeNode)

JTree(TreeNode, boolean)
JTree(TreeModel)
JTree()
JTree(Hashtable)
JTree(Object[])
JTree(Vector)
创建树。 TreeNode参数指定由默认树模型 管理 的根节点。 TreeModel参数指定将数据提供给表的模型。此构造函数的无参数版本供构建器使用。它创建了一个包含一些 samples 数据的树。如果您指定Hashtable,对象数组或Vector作为参数,则该参数将被视为根节点下的节点列表(未显示),并相应地构建模型和树节点。
boolean参数(如果存在)指定树应如何确定是否应将节点显示为叶。如果参数为 false(默认值),则任何没有子节点的节点都将显示为叶。如果参数为 true,则仅当其getAllowsChildren方法返回 false 时,节点才是叶子。
void setCellRenderer(TreeCellRenderer)设置绘制每个节点的渲染器。
void setEditable(boolean)
void setCellEditor(TreeCellEditor)
第一种方法设置用户是否可以编辑树节点。默认情况下,树节点不可编辑。第二套用于定制的编辑器。
void setRootVisible(boolean)设置树是否显示根节点。如果使用使用数据结构的构造函数之一创建树,则默认值为 false,否则为 true。
void setShowsRootHandles(boolean)设置树是否显示其最左侧节点的句柄,以便您展开和折叠节点。默认为 false。如果树未显示根节点,则应调用setShowsRootHandles(true)
void setDragEnabled(boolean)
boolean getDragEnabled()
设置或获取dragEnabled属性,该属性必须为 true 以启用对此组件的拖动处理。默认值为 false。有关更多详细信息,请参见拖放和数据传输

Implementing Selection

MethodPurpose
void addTreeSelectionListener(TreeSelectionListener)注册侦听器以检测何时选择或取消选择节点。
void setSelectionModel(TreeSelectionModel)

TreeSelectionModel getSelectionModel()
设置或获取用于控制节点选择的模型。您可以使用setSelectionModel(null)完全关闭节点选择。
void setSelectionMode(int)
int getSelectionMode()
(在TreeSelectionModel中)
设置或获取选择 Pattern。该值可以是CONTIGUOUS_TREE_SELECTIONDISCONTIGUOUS_TREE_SELECTIONSINGLE_TREE_SELECTION(均在TreeSelectionModel中定义)。
Object getLastSelectedPathComponent()获取代表当前选定节点的对象。这等效于对tree.getSelectionPath()返回的值调用getLastPathComponent
void setSelectionPath(TreePath)
TreePath getSelectionPath()
设置或获取当前所选节点的路径。
void setSelectionPaths(TreePath[])
TreePath[] getSelectionPaths()
设置或获取当前选定节点的路径。
void setSelectionPath(TreePath)
TreePath getSelectionPath()
设置或获取当前所选节点的路径。

显示和隐藏节点

MethodPurpose
void addTreeExpansionListener(TreeExpansionListener)

void addTreeWillExpandListener(TreeWillExpandListener)
注册一个侦听器以分别检测树节点何时已扩展或折叠,或何时将扩展或折叠。要否决即将发生的扩展或崩溃,TreeWillExpandListener可以抛出ExpandVetoException
void expandPath(TreePath)
void collapsePath(TreePath)
展开或折叠指定的树路径。
void scrollPathToVisible(TreePath)确保该路径指定的节点是可见的—指向该路径的路径已展开,并且该节点在滚动窗格的查看区域中。
void makeVisible(TreePath)确保该路径指定的节点是可见的-指向该路径的路径已展开。该节点可能不会在查看区域内结束。
void setScrollsOnExpand(boolean)
boolean getScrollsOnExpand()
设置或获取树是否try滚动以显示先前的隐藏节点。缺省值为 true。
void setToggleClickCount(int)
int getToggleClickCount()
设置或获取节点展开或关闭之前的鼠标单击次数。缺省值为 2.
TreePath getNextMatch(String,int,Position.Bias)TreePath返回到以特定前缀开头的下一个树元素。

使用树的示例

下表列出了使用JTree的示例,并在其中描述了这些示例。

ExampleWhere DescribedNotes
TreeDemo创建一棵树, 响应节点选择, 自定义树的显示创建一个响应用户选择的树。它还具有用于自定义 Java 外观的线条样式的代码。
TreeIconDemo自定义树的显示将自定义叶子图标添加到 TreeDemo。
TreeIconDemo2自定义树的显示自定义某些叶子图标,并提供某些树节点的工具提示。
DynamicTreeDemo动态改变树说明了从树中添加和删除节点。还允许编辑节点文本。
GenealogyExample创建数据模型实现自定义树模型和自定义节点类型。
TreeExpandEventDemo如何编写树扩展侦听器显示如何检测节点的膨胀和收缩。
TreeExpandEventDemo2如何编写一个树状扩展侦听器显示如何否决节点扩展。

如果您使用 JavaFX 编程,请参见Tree View