2

我正在使用 CheckBoxTree 组件来获得一种带有复选框的特殊 JTree。但是,我希望能够在高级节点上没有复选框,因为它们永远不应该被选中,它们只是“分支的名称”。这是树的一个简单示例:

元数据 - 产品 - 产品 A - 产品 B - 等等 - 模型 - 等等

因此,节点“元数据”是树模型的根。由于提供了方便的 setRootVisible 方法(如在 JTree 中),该节点是不可见的。但除了使根不可见之外,我还希望删除第二级复选框。所以基本上,应该只有来自 prod A、prod B 等和向下级别的复选框(可以低几个级别)。但我仍然想要二级的标签。

我尝试根据描述 checkboxtree 组件的该站点实现自定义 CheckboxTreecellRenderer:

http://www.javaworld.com/javaworld/jw-09-2007/jw-09-checkboxtree.html?page=3

不幸的是,这不起作用。与网站上的示例相比,我尝试移动添加标签和按钮(我不会使用单选按钮,只是使用它来尝试删除标签以保持简单,但我仍然会如果我让它以某种方式工作,请使用复选框)。我移动它们是为了尝试仅在节点将元数据节点作为其父节点时才设置按钮,从而从第二级删除按钮。

但这没有用。令人惊讶的是,这个概念本身似乎有效,因为 button.setEnabled(false); (在下面注释掉)确实有效。这会禁用正确级别的按钮。但是,如果我尝试不在那里添加按钮,那么我在任何地方都没有按钮......

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package se.expertinfo.ditaplugin;

import it.cnr.imaa.essi.lablib.gui.checkboxtree.CheckboxTree;
import it.cnr.imaa.essi.lablib.gui.checkboxtree.CheckboxTreeCellRenderer;
import it.cnr.imaa.essi.lablib.gui.checkboxtree.TreeCheckingModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.tree.TreePath;

/**
 *
 * @author Anders
 */
public class CustomTreeCellRenderer implements CheckboxTreeCellRenderer {

    JPanel panel = new JPanel();
    JLabel label = new JLabel();
    JRadioButton button = new JRadioButton();

    public CustomTreeCellRenderer() {
        label.setFocusable(true);
        label.setOpaque(true);
        panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
//        panel.add(button);
//        panel.add(label);
        button.setBackground(UIManager.getColor("Tree.textBackground"));
        panel.setBackground(UIManager.getColor("Tree.textBackground"));
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {
        label.setText(value.toString());
        if (selected) {
            label.setBackground(UIManager.getColor("Tree.selectionBackground"));
        } else {
            label.setBackground(UIManager.getColor("Tree.textBackground"));
        }
        TreeCheckingModel checkingModel = ((CheckboxTree) tree).getCheckingModel();

        TreePath path = tree.getPathForRow(row);


        boolean enabled = checkingModel.isPathEnabled(path);
        boolean checked = checkingModel.isPathChecked(path);
        boolean grayed = checkingModel.isPathGreyed(path);

        button.setEnabled(enabled);

        if (path != null) {
            TreePath parent = path.getParentPath();
            if (parent != null) {
                if (parent.getLastPathComponent().toString().equalsIgnoreCase("metadata")) {
//                    button.setEnabled(false);                    
                    panel.add(label);
                } else {                    
                    panel.add(button);
                    panel.add(label);
                    button.setSelected(checked);
                }
            }
        }


        if (grayed) {
            label.setForeground(Color.lightGray);
        } else {
            label.setForeground(Color.black);
        }
        button.setSelected(checked);
        return panel;
    }

    @Override
    public boolean isOnHotspot(int x, int y) {
        return (button.getBounds().contains(x, y));
    }
}
4

1 回答 1

2

示例isLeaf()在 的实现中使用,isCellEditable()以将编辑仅限于叶节点。

附录:要排除在某个级别以上的编辑,您可以使用如下谓词检查路径上的元素数量:path.getPathCount() > 2.

于 2012-12-27T15:39:34.017 回答