4

我在 Swing 中工作,我想禁用特定类型节点上的扩展(加号 [+])符号。

不知道该怎么做,因为我的节点不是叶子而且我也不能使用setShowsRootHandles(仅用于根)。

我指的是 JTree:假设我有这个结构:

--[+] 节点1

--[+] 节点2

当我加载这个结构时,我不想在 node2 上看到 [+] 符号(因为它是一个特殊类型的节点)。但我也想通过使用特殊命令来扩展它。

我已经覆盖了 isLeaf() (来自 DefaultMutableTreeNode 的方法),所以当我在特殊类型节点中时它会设置为 TRUE,但是当我尝试扩展它时,它不会扩展,因为 isLeaf() = = 真...

希望这会让事情变得更清楚。

4

2 回答 2

3

虽然无法移除句柄,但可以限制节点的扩展。要走的路是 TreeWillExpandListener 与具有限制扩展状态的自定义 treeNode 相结合:

  • 下面的自定义节点有一个默认为 false 的可扩展属性
  • 检测自定义节点时,侦听器允许/否决基于该可扩展属性的扩展
  • 对于程序化扩展,expandable 属性暂时设置为 true 以通过监听器

示例代码:

// mixed tree of normal/restricted noded
DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
DefaultMutableTreeNode normalSubTree = new DefaultMutableTreeNode("normal");
normalSubTree.add(new DefaultMutableTreeNode("normalChild"));
MyNode restrictedSubTree = new MyNode("restrictedSubtree");
restrictedSubTree.add(new DefaultMutableTreeNode("restrictedChild"));
root.add(normalSubTree);
root.add(restrictedSubTree);
final JTree tree = new JTree(root);
// the listener which vetos expansion of MyNodes that are not expandable
TreeWillExpandListener l = new TreeWillExpandListener() {

    @Override
    public void treeWillExpand(TreeExpansionEvent event)
            throws ExpandVetoException {
        TreePath path = event.getPath();
        if (path.getLastPathComponent() instanceof MyNode) {
            if (!((MyNode) path.getLastPathComponent()).isExpandable()) {
                throw new ExpandVetoException(event, "node not expandable");
            }
        }
    }

    @Override
    public void treeWillCollapse(TreeExpansionEvent event)
            throws ExpandVetoException {
    }
};
tree.addTreeWillExpandListener(l);

Action expand = new AbstractAction("Expand") {

    @Override
    public void actionPerformed(ActionEvent e) {
        TreePath selected = tree.getSelectionPath();
        if (selected == null) return;
        if (selected.getLastPathComponent() instanceof MyNode) {
            MyNode last = (MyNode) selected.getLastPathComponent();
            boolean old = last.isExpandable();
            last.setExpandable(true);
            tree.expandPath(selected);
            last.setExpandable(old);
        }
    }
};

    JXFrame frame = wrapWithScrollingInFrame(tree, "veto expand");
    addAction(frame, expand);
    show(frame);
}

// custom node which has an expandable property
public static class MyNode extends DefaultMutableTreeNode {

    private boolean expandable;

    public MyNode() {
        this(null);
    }

    public MyNode(Object userObject) {
        super(userObject);
    }

    public void setExpandable(boolean expandable) {
        this.expandable = expandable;
    }

    public boolean isExpandable() {
        return expandable;
    }
}
于 2013-10-20T09:50:35.273 回答
1

尽管其他人提到了什么,但可以移除手柄。我在下面附上了一个关于如何做到这一点的片段。关键是shouldPaintExpandControlBasicTreeUI.

jtree.setUI(new BasicTreeUI() {
    @Override
    protected boolean shouldPaintExpandControl(final TreePath path, final int row
            , final boolean isExpanded, final boolean hasBeenExpanded, final boolean isLeaf)
    {
        boolean shouldDisplayExpandControl = false;
        return shouldDisplayExpandControl;
    }

这确实应该记录在 JTree API 中,但这是另一个问题。


要考虑的另一种方法:

如果您调用DefaultTreeModel(TreeNode root, boolean asksAllowsChildren)模型,将“询问”您插入的节点是否允许有子节点。如果不能,则不应显示展开图标。

一定要javax.swing.tree.TreeNode.getAllowsChildren()在你的课堂上覆盖。

于 2013-12-10T13:23:06.630 回答