首先声明菜鸟编写,误导自负!!!
就像我一直提倡的那样,在网上找答案通常情况下是找到废答案一堆,而且解决了也不一定明白为什么,所以看官方的文档是那么的重要哈。关于下载官方教程的问题请看:点击打开链接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);