繁体   English   中英

设置新的 TreeModel 时如何自动扩展 JTree?

[英]How do I auto-expand a JTree when setting a new TreeModel?

我有一个自定义JTree和一个自定义JModel 当我给它一个新模型时,我希望 JTree 能够“自动扩展”。 目前,它只是将所有节点折叠到根节点。

下面是一个例子:

private class CustomTree extends JTree {

    @Override
    public boolean isExpanded(TreePath path) {
        return ((Person) path.getLastPathComponent).hasChildren();

}

private class CustomTreeModel extends TreeModel {

    // ... omitting various implementation details

    @Override
    public boolean isLeaf(Object object) {
        return !((Person) object).hasChildren();
    }

}

Model model = new Model();
Person bob = new Person();
Person alice = new Person();
bob.addChild(alice);
model.setRoot(bob);
JTree tree = new CustomTree(new CustomTreeModel(model));

此时,树正确显示:

- BOB
  - ALICE

其中 Alice 是 Bob 的孩子(在数据和可视化树中)

但是,如果我打电话:

tree.setModel(new CustomTreeModel(model));

一切都崩溃了:

+ BOB

有没有办法在设置新模型时“自动扩展”树中的所有内容?

以下对我有用(在设置新模型后调用):

for (int i = 0; i < tree.getRowCount(); i++) {
    tree.expandRow(i);
}

我有一个类似的问题。

您的解决方案(如https://stackoverflow.com/a/15211697/837530发布)似乎仅适用于顶级树节点。

但是我需要扩展所有的后代节点。 所以我用下面的递归方法解决了它:

private void expandAllNodes(JTree tree, int startingIndex, int rowCount){
    for(int i=startingIndex;i<rowCount;++i){
        tree.expandRow(i);
    }

    if(tree.getRowCount()!=rowCount){
        expandAllNodes(tree, rowCount, tree.getRowCount());
    }
}

这是用

expandAllNodes(tree, 0, tree.getRowCount());

其中, treeJTree

除非有人有更好的解决方案。

还有这个非递归版本。

private void expandAllNodes(JTree tree) {
    int j = tree.getRowCount();
    int i = 0;
    while(i < j) {
        tree.expandRow(i);
        i += 1;
        j = tree.getRowCount();
    }
}

这对我有用..

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Enumeration;

public class JTreeNodeAutoExpandCollapse extends JFrame {
    public JTreeNodeAutoExpandCollapse() throws HeadlessException {
        initializeUI();
    }

    private void initializeUI() {
        setSize(200, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
        DefaultMutableTreeNode chapter1 = new DefaultMutableTreeNode("Chapter 1");
        DefaultMutableTreeNode sub1 = new DefaultMutableTreeNode("1.1");
        DefaultMutableTreeNode sub2 = new DefaultMutableTreeNode("1.2");
        DefaultMutableTreeNode sub3 = new DefaultMutableTreeNode("1.3");
        DefaultMutableTreeNode sub31 = new DefaultMutableTreeNode("1.3.1");
        DefaultMutableTreeNode sub32 = new DefaultMutableTreeNode("1.3.2");

        root.add(chapter1);
        chapter1.add(sub1);
        chapter1.add(sub2);
        chapter1.add(sub3);
        sub3.add(sub31);
        sub3.add(sub32);

        final JTree tree = new JTree(root);
        expandTree(tree, false);

        JScrollPane pane = new JScrollPane(tree);
        pane.setPreferredSize(new Dimension(200, 200));

        JPanel buttonPanel = new JPanel(new BorderLayout());
        JButton expandAll = new JButton("Expand All");
        expandAll.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                expandTree(tree, true);
            }
        });

        JButton collapseAll = new JButton("Collapse All");
        collapseAll.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                expandTree(tree, false);
            }
        });

        buttonPanel.add(expandAll, BorderLayout.WEST);
        buttonPanel.add(collapseAll, BorderLayout.EAST);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(pane, BorderLayout.CENTER);
        getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    }

    private void expandTree(JTree tree, boolean expand) {
        TreeNode root = (TreeNode) tree.getModel().getRoot();
        expandAll(tree, new TreePath(root), expand);
    }

    private void expandAll(JTree tree, TreePath path, boolean expand) {
        TreeNode node = (TreeNode) path.getLastPathComponent();

        if (node.getChildCount() >= 0) {
            Enumeration enumeration = node.children();
            while (enumeration.hasMoreElements()) {
                TreeNode n = (TreeNode) enumeration.nextElement();
                TreePath p = path.pathByAddingChild(n);

                expandAll(tree, p, expand);
            }
        }

        if (expand) {
            tree.expandPath(path);
        } else {
            tree.collapsePath(path);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTreeNodeAutoExpandCollapse().setVisible(true);
            }
        });
    }
}

由于我无法编辑或评论接受OP的最后一个问题的接受答案:

在设置新模型时,有没有办法“自动扩展”树中的所有内容?

要在分配新模型后(根据OP的请求)展开树,请覆盖自定义树中的treeDidChange()

@Override 
public void treeDidChange() { 
    super.treeDidChange(); 
    expandAllNodes(this, 0, getRowCount());
} 
public void expandTree(){
    int row = 1;
    while (row++ < tree.getRowCount()){
        tree.expandRow(row);
    }

public void collapseTree(){
    int row = tree.getRowCount() - 1;
    while (row-- > 0){
        tree.collapseRow(row);
    }
}
TreeUtils.expandAll(tree, true);

您将从jidesoft获得TreeUtils。 这不是开源库,但如果你有它,你可以简单地扩展所有的treenode。

http://www.jidesoft.com/javadoc/com/jidesoft/tree/TreeUtils.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM