最近在写一个类似QQ的聊天小项目,遇到好友列表的设计,查了许多文章没有一篇写的比较完整的例子。所以自己将该Demo详细的过程写下来,供大家参考,有错误的欢迎指出。
一、概述
要使用JTree实现好友列表,就要调用JAVA本身自带的类库所提供的方法。但是JTree本身提供的方法设计出来的树是有默认的排版,没有美感,比较死板。代码和图如下:
//设置练个节点,一个父节点,一个子节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
root.add(new DefaultMutableTreeNode());
root.add(new DefaultMutableTreeNode());
root.add(new DefaultMutableTreeNode());
root.add(new DefaultMutableTreeNode());
root.add(new DefaultMutableTreeNode());
//只要将父节点加入JTree中即可
JTree tree = new JTree(jMode);
二、实现自定的JTree
在现实的开发中,不可能用上述的默认排版进行设计列表,所以要自己设计跟项目对应的外观。
想要对JTree进行外观的渲染就要应用到 DefaultTreeCellRenderer类,该类中有提供一个设置每个节点的自定义设置方法。并且DefaultTreeCellRenderer类跟JLabel类相似,由此可知DefaultTreeCellRenderer类的对象可以当做平常的JLabel进行相应的设置大小、位置、字体、图片等等相关的自定义设置。
1、重写TreeNode类
通过重写TreeNode类可以实现某一个节点中所要包含的某些字段,我的这个Demo中自己设置了帐号、昵称、头像、是否在线,这几个信息。代码如下:
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;
public class FriendNode extends DefaultMutableTreeNode{
protected ImageIcon icon;
protected long userAccount;
protected String NickName;
protected long isOnline;
public FriendNode()
{
}
/**
* 只包含好友昵称和是否在线的节点构造函数
* @param NickName
* @param isOnline
*/
public FriendNode(String NickName,long isOnline)
{
super();
this.NickName=NickName;
this.isOnline=isOnline;
}
/**
* 包含好友头像、昵称、是否在线的节点构造函数
* @param icon
* @param NickName
* @param isOnline
*/
public FriendNode(ImageIcon icon,String NickName,long isOnline,long userAccount)
{
super();
this.icon=icon;
this.NickName=NickName;
this.isOnline=isOnline;
this.userAccount=userAccount;
}
public ImageIcon getIcon() {
return icon;
}
public void setIcon(ImageIcon icon) {
this.icon = icon;
}
public String getNickName() {
return NickName;
}
public void setNickName(String nickName) {
NickName = nickName;
}
public long getIsOnline() {
return isOnline;
}
public void setIsOnline(long isOnline) {
this.isOnline = isOnline;
}
public long getUserAccount() {
return userAccount;
}
public void setUserAccount(long userAccount) {
this.userAccount = userAccount;
}
}
2、重写渲染节点类DefaultTreeCellRenderer
重写TreeNode类后,还要自己重写对节点进行渲染的修饰类。在本Demo中,将每个好友的相对关健的信息放在了一个JLabel的对象上面,然后每个节点就是对应的一个Label。具体对Label的一些修饰代码如下(修饰的方法都有注释):
import java.awt.Component;
import java.awt.Image;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
public class FriendNodeRenderer extends DefaultTreeCellRenderer{
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);
//将value转化为节点对象
FriendNode friendNode=(FriendNode)value;
//从节点中读取图片并且将图片自适应大小、居中
ImageIcon icon=new ImageIcon(friendNode.getIcon()+"");
icon.setImage(icon.getImage().getScaledInstance(50,50,Image.SCALE_DEFAULT));
//从节点中读取昵称和是否在线
String isOnline="离线";
String text="";、
//因为在Label中文本文字不能够通过调用相应的方法进行换行,
//所以通过使用html的语法对文字进行换行
if(friendNode.getIsOnline()==0)
{
isOnline="[离线]";
text="<html>" + friendNode.getNickName() + "<br/>" + isOnline + " <html/>";
}
else if(friendNode.getIsOnline()==1){
isOnline="[在线]";
text="<html>" + friendNode.getNickName() + "<br/>" + isOnline + " <html/>";
}
else if(friendNode.getIsOnline()==3){
text=friendNode.getNickName();
}
//设置图片
setIcon(icon);
//设置文本
setText(text);
//设置图片和文本之间的距离
setIconTextGap(15);
return this;
}
}
3、调用自己重写的两个类设置JTree
设计JTree的时候,可以将tree添加到JScrollPane,这样的话,当树节点在一个可见窗口的范围中显示不下的时候,就可以通过滚动条来移动。其中tree.setCellRenderer(new FriendNodeRenderer());这句代码非常重要,只有将JTree设置成单元描述,自己定义的树外观才能显示出来,不然还是显示树的默认外观。核心的的实现代码如下:
//用刚才自定义的节点类来创建树节点,并且添加自定义的属性
FriendNode root=new FriendNode("我的好友",3);
FriendNode node1=new FriendNode(new ImageIcon ("Image//1.jpg"),"好友1",1);
FriendNode node2=new FriendNode(new ImageIcon ("Image//2.jpg"),"好友1",0);
FriendNode node3=new FriendNode(new ImageIcon ("Image//2.jpg"),"好友1",0);
FriendNode node4=new FriendNode(new ImageIcon ("Image//2.jpg"),"好友1",0);
FriendNode node5=new FriendNode(new ImageIcon ("Image//2.jpg"),"好友1",0);
//将所有的子节点加入到根节点中,当然也可以一个节点再次添加
//下一个节点,这样的话就可以呈现出多级的树形结果
root.add(node1);
root.add(node2);
root.add(node3);
root.add(node4);
root.add(node5);
//将刚才的根节点添加到JTree中
JTree tree=new JTree(root);
//将树的前面连接去掉
tree.putClientProperty("JTree.lineStyle", "Horizontal");
//设置树的字体大小,样式
tree.setFont(new Font("微软雅黑", Font.PLAIN, 15));
//设置树节点的高度
tree.setRowHeight(80);
//设置单元描述
tree.setCellRenderer(new FriendNodeRenderer());
//添加树的双击触发事件
tree.addMouseListener(new MouseHandle());
//将tree添加到JScrollPane 中
JScrollPane scrollPane=new JScrollPane();
scrollPane.setViewportView(tree);
//将scrollPane添加到JPanel中用于显示
containerCenter.add(scrollPane);
4、最后的显示结果如下:
三、总结
要想利用JTree实现好友列表,就必须重写TreeNode类和DefaultTreeCellRenderer类,主要对JTree默认框架其重要作用的就是DefaultTreeCellRenderer类中的getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);方法。只有重写改方法就可以自定义JTree的外观。