使用JTree中遇到的问题。如设置叶子底色,并将搜索到的node显示在窗口中央。

首先声明菜鸟编写,误导自负!!!

就像我一直提倡的那样,在网上找答案通常情况下是找到废答案一堆,而且解决了也不一定明白为什么,所以看官方的文档是那么的重要哈。关于下载官方教程的问题请看:点击打开链接http://blog.csdn.net/xuanyuanlei1020/article/details/43194989

我是以我要解决的问题排列自己的文章的,废话没有。开始!

所有的代码,在tutorial中都可以找到,所以没必要复制等等。

一. 实现叶节点的高亮(即背景色为黄色)

找到官方tutorial的关于Jtree的教程,会有这样一段话:

If you want finer control over the node icons or you want to provide tool tips, you can do so by creating a subclass of DefaultTreeCellRenderer and overriding the getTreeCellRendererComponent method. Because DefaultTreeCellRenderer is a subclass of JLabel, you can use any JLabel method — such as setIcon — to customize the DefaultTreeCellRenderer.
The following code, from TreeIconDemo2.java, creates a cell renderer that varies the leaf icon depending on whether the word "Tutorial" is in the node's text data. The renderer also specifies tool-tip text, as the bold lines show.

翻译:

如果你想更好的控制节点图标或你想提供工具提示,你可以通过创建一个子类DefaultTreeCellRenderer和覆盖的方法getTreeCellRendererComponent 因为DefaultTreeCellRenderer 是JLabel的子类,所以我们可以使用任何针对JLabel的方法,例如setIcon,来定制DefaultTreeCellRenderer的属性。


通过这一段话,我们知道,原来对tree的操作,原来可以像对JLabel一样操作,所以,什么setBackground都可以用了。

下面是代码。

//...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;
    }
}
但是我要实现的是像实现搜索功能,现在在生成Tree的过程中,实现高亮是没有意义的,所以,我开始继续看教程。
结果发现没有我想要的代码,好伤心啊。只好自己根据自己已知的知识进行实验了。

首先,应该确定,整个Tree是一个JComponent,而节点都是一个个cell,所以直接对节点进行setBackgroudColor是不正确的。应该对整个Tree进行使用,而这样又是不对的,因为那样就将整个Tree高亮了。经过实验可以确定在生成Tree后再调用

tree.setCellRenderer

也是可以的。

所以在MyRenderer中实现字符串的对比,进行相关节点的高亮就实现了。其中窗口焦点的设定同理。注意查看

etTreeCellRendererComponent
的API文档。

2015-02-05 更正:直接使用MyRenderer是没有用的,因为通过实验发现,它是对能看到的节点有效果,而对不能看到的(就是未展开的节点是没有效果的)我的解决办法是:将相关的节点先打开,然后在进行设置cellRenderer。

对我很有帮助的帖子是:点击打开链接  http://bbs.csdn.net/topics/360024901 主要是对两个Api函数的理解:

treenode.preorderEnumeration() //前序遍历-->当前节点之后(子节点)正序枚举数列,常用于展开
treenode.postorderEnumeration() //后序遍历-->当前节点之后(子节点)倒序枚举数列,常用于折叠

我自己写了个处理相关节点展开和折叠的类,大家可以直接借鉴,如果大家有什么好想法,请给我留言。

文件下载地址:点击打开链接 http://download.csdn.net/detail/xuanyuanlei1020/8428499

import java.util.Enumeration;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

/**
 * Author:Tom Hu ;2015-02-06
 * Class Name:SwingUtil.java
 * Purpose:Do some expand and collapse job.
 * Email:xuanyuanlei1020@163.com
 */
public class SwingUtil
{
	/**
	 * Method Name:expandAll
	 * Purpose:将此树的所有子节点都展开
	 */
	public static void expandAll(JTree tree)
	{
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel()
				.getRoot();
		expandTreeFromNode(tree, root);
	}

	/**
	 * Method Name:expandTreeFromNode
	 * Purpose:展开指定的节点。
	 */
	public static void expandTreeFromNode(JTree tree,
			DefaultMutableTreeNode nodeToE)
	{
		Enumeration<?> enumeration = nodeToE.preorderEnumeration();
		while (enumeration.hasMoreElements())
		{
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration
					.nextElement();
			if(!node.isLeaf())
			{
//				System.out.println("found" + node);
				TreePath path = new TreePath(node.getPath());
				tree.expandPath(path);
			}
		}
	}

	/**
	 * Method Name:makeVisiableTo
	 * Purpose:使某个节点可见(即使其所有父节点都展开)
	 */
	public static void makeVisibleTo(JTree tree, DefaultMutableTreeNode nodeToV)
	{
//		System.out.println("found" + nodeToV);
		TreePath path = new TreePath(nodeToV.getPath());
		tree.makeVisible(path);
	}

	/**
	 * Method Name:collapseAll
	 * Purpose:将整个树都折叠上。
	 */
	public static void collapseAll(JTree tree)
	{
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel()
				.getRoot();
		collapseTreeToNode(tree, root);
	}

	/**
	 * Method Name:collapseTreeToNode
	 * Purpose:将某个节点所有的子节点都折叠
	 */
	public static void collapseTreeToNode(JTree tree,
			DefaultMutableTreeNode nodeToC)
	{
		Enumeration<?> enumeration = nodeToC.postorderEnumeration();
		while (enumeration.hasMoreElements())
		{
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration
					.nextElement();
			if(!node.isLeaf())
			{
//				System.out.println("found" + node);
				TreePath path = new TreePath(node.getPath());
				tree.collapsePath(path);
			}
		}
	}

	/**
	 * 
	 * Method Name:collapseTreeBeforeRoot
	 * Purpose:展仅展开根目录的下一级
	 */
	public static void collapseTreeBeforeRoot(JTree tree)
	{
		DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel()
				.getRoot();
		for (int i = 0; i < root.getChildCount(); i++)
		{
			DefaultMutableTreeNode nodeToC = (DefaultMutableTreeNode) root
					.getChildAt(i);
			collapseTreeToNode(tree, nodeToC);
		}
	}

	/**
	 * Method Name:expandAndCollapseOther
	 * Purpose:将nodeToE这个节点可见,并将其他节点折叠
	 */
	public static void expandAndCollapseOther(JTree tree,
			DefaultMutableTreeNode nodeToE)
	{
		collapseTreeBeforeRoot(tree);
		makeVisibleTo(tree,nodeToE);
	}
}
通过上面这种思想,我基本上实现了node的高亮。而且效果还不错。

对于实现,将一条条的搜索到的node展现在窗口中央,其具体方法就是将相应的node找到,并通过以下代码实现。

TreePath tp = new TreePath(node.getPath());
localTree.scrollPathToVisible(tp);




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值