Java 如何在Swing JTree中禁用扩展登录?

Java 如何在Swing JTree中禁用扩展登录?,java,swing,jtree,expand,Java,Swing,Jtree,Expand,我在Swing中工作,我想在特定类型的节点上禁用扩展(加号[+]) 我不知道该怎么做,因为我的节点不是叶子,而且我也不能使用setShowsRootHandles(这只适用于根节点) 我指的是JTree:假设我得到这个结构: 根 --[+]节点1 --[+]节点2 加载此结构时,我不希望在node2上看到[+]符号(因为它是一个特殊类型的节点)。但我还想通过使用一个特殊命令来扩展它 我已经重写了isLeaf()(DefaultMutableTreeNode中的方法),所以当我在特殊类型节点中时,

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

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

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

--[+]节点1

--[+]节点2

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

我已经重写了isLeaf()(DefaultMutableTreeNode中的方法),所以当我在特殊类型节点中时,它会设置为TRUE,但是当我尝试展开它时,它不会展开,因为isLeaf()==TRUE


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

虽然无法移除句柄,但可以限制节点的扩展。方法是将TreeWireExpandListener与具有限制扩展状态的自定义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;
    }
}

不管其他人怎么说,都可以移除把手。 我在下面附上了一个关于如何做到这一点的片段。关键是在
basictreui
中重写
shoulldpaintexpandcontrol

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;
    }
这应该在JTreeAPI中记录,但这是另一个问题


考虑的另一种方法:

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


确保在类中重写
javax.swing.tree.TreeNode.getAllowsChildren()

欢迎使用SO。你没有给我们任何关于你问题的细节。事实上,我们不知道节点是什么意思,正因为如此,你的所有问题都不清楚。另外,你没有向我们展示任何试图解决这个问题的努力,至少提供你的代码。我猜你指的是
JTree
,因为它包含节点,并且有一个同名的方法。我不喜欢猜测。为了更快地获得更好的帮助,请发布一个。添加一个TreeWillExpandListener并否决您不想扩展的节点的扩展:但不会给出任何关于该节点是否可扩展的视觉线索。嘿,伙计们,今天是星期天上午(至少在柏林这里)-在投票关闭之前给他/她一个改进问题的机会!伙计们,谢谢你们的快速回复。我已经更新了问题。@user2899630:您也可以更改图标,如图所示。@trashgood-hmm。。我认为(当然可能是错误的:-)OP表示展开/折叠句柄(相对于节点图标)?我认为你是正确的;我的意思是建议一种产生这种效果的额外方法,尽管它在大多数UI实现中都保留了句柄+1对于监听器,顺便说一句,这不是一个真正的选项:a)ui的手动每个实例设置非常脆弱(每当触发更新时就会丢失)b)子类化BasicXX将丢失所有每个laf的特殊功能,并且看起来。。。甚至比核心Laf还要难看。如果您确实想要它(并且可能会让您的用户感到困惑),请根据支持的LAF实现自定义ui委托,并向UIManager注册该委托+1用于跟踪覆盖所取点的确切方法。我增加了做同样事情的另一种方法。