最近学习了一下JTree的使用方法:

先来看一下树的实例:

构建一个树,

DefaultMutableTreeNode root = new DefaultMutableTreeNode("根节点");
DefaultMutableTreeNode node = new DefaultMutableTreeNode("节点1");
root.add(node);
root.add(new DefaultMutableTreeNode("叶子节点3"));
node.add(new DefaultMutableTreeNode("叶子节点1"));
node.add(new DefaultMutableTreeNode("叶子节点2"));
DefaultTreeModel jMode = new DefaultTreeModel(root);
JTree tree = new JTree(jMode);

下面就是添加数据之后,java中默认的样式,

然后我们可以来改变数中的节点的图片,以及打开,折叠的样子:

DefaultTreeCellRenderer  render=(DefaultTreeCellRenderer )tree.getCellRenderer();
//设置tree非叶子节折叠时的图片;
render.setClosedIcon(new ImageIcon(this.getClass().getResource("Arrow_right.png")));
//设置tree非叶子节点展开时的图片
render.setOpenIcon(new ImageIcon(this.getClass().getResource("right.png")));
//设置tree叶子节点的图片
render.setLeafIcon(new ImageIcon(this.getClass().getResource("chat_32.png")));

如图:

然后我们还可以来把前面的连接线给去掉:

tree.putClientProperty("JTree.lineStyle", "Horizontal");// 将树设为水平分隔风格

如图:

其他的一些基本设置:

  tree.setFont(new Font(Font.SANS_SERIF, Font.LAYOUT_LEFT_TO_RIGHT, 18));
//字体的大小,样式
tree.setRowHeight(50);//树节点的高度
tree.setToggleClickCount(1); //设置展开节点之前的鼠标单击数为1
//设置一次自能选中一个节点 tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setRootVisible(false);// 设置根节点为不可见;

如图:

所以从上面我们可以看出来,JTree的是由TreeNode构成的;

JTree和JList一样,都有一个Model以及TreeCellRenderer渲染器,树用Model模型来管理TreeNode,然后TreeCellRenderer渲染器则是负责Tree的样式。

我们也可以像JList一样通过重写来实现自定义的树。但是这里JTree需要改写的不是Model,而是TreeNode。

JTree,TreeModel,以及TreeNode,以及TreeCellRenderer:

在JTree中,每一个JTree由N个TreeNode构成,而TreeModel管理的是所有的TreeNode。TreeCellRenderer则是负责渲染每一个TreeNode。

TreeNode:在JTree中,可以说是负责数据的存储。在默认的节点DefaultMutableTreeNode中,JTree上显示的数据也就是文字是放的属性userObject(是一个Object对象)中,在上面的例子中我们的userObject存放的就是String型的对象。

TreeMode:是模型,也就是说,他负责把所有的TreeNode给联系起来。通过TreeMode我们可以知道,当前树的总的节点数,以及是否为叶子节点等。

TreeCellRenderer:渲染器,JAVA提供的渲染器,一般是一个JLabel对象,然后实现了TreeCellRenderer接口。根据Model传来的对象,进行包装——把该对象转换为String型然后显示在JLable上面。在TreeCellRenderer渲染器中得到的Value的值是一个TreeNode对象,TreeCellRenderer渲染的是每一个TreeNode。

自定义好友列表:

1.实现TreeNode,在自定义好友列表的TreNode里面,需要显示好友的名字(uName),以及个性签名(text),然后是一个头像(img),然后ID是用来唯一标示该节点,存储的是好友的ID。然后是考虑到数型结构,会有孩子节点(可以有多个孩子所以为一个数组),以及父节点。

public class FriTreeNode implements TreeNode{

	private String ID;//该节点的ID号
private ImageIcon img;//节点存放图片
private String uName;//第一行文字(显示名字)
private String text;//第二行文字(显示签名) private ArrayList<TreeNode> children;//孩子节点
private TreeNode parent;//父亲节点 public FriTreeNode(String ID) {
this.ID=ID;
}
public FriTreeNode() { }
public FriTreeNode(String name,String text,ImageIcon img,String ID) {
this.uName=name;
this.text=text;
this.img=img;
this.ID=ID;
} /**
* @return the iD
*/
public String getID() {
return ID;
}
/**
* @param iD the iD to set
*/
public void setID(String iD) {
ID = iD;
}
/**
* @return the uName
*/
public String getuName() {
return uName;
}
/**
* @param uName the uName to set
*/
public void setuName(String uName) {
this.uName = uName;
}
/**
* @param parent the parent to set
*/
public void setParent(FriTreeNode parent) {
this.parent = parent;
} /**
* @return the img
*/
public ImageIcon getImg() {
return img;
} /**
* @param img the img to set
*/
public void setImg(ImageIcon img) {
this.img = img;
} /**
* @return the text
*/
public String getText() {
return text;
} /**
* @param text the text to set
*/
public void setText(String text) {
this.text = text;
} public void addchild(FriTreeNode aChild){ if(children==null){
children=new ArrayList<TreeNode>();
}
children.add(aChild);
aChild.parent=this;
}
/***
* 判断是否为根节点
* @return
*/
public boolean isroot(){ return (getParent()==null); } @Override
public TreeNode getChildAt(int childIndex) {
if (children == null) {
throw new ArrayIndexOutOfBoundsException("node has no children");
}
return children.get(childIndex) ;
} @Override
public int getChildCount() {
if (children == null) {
return -1 ;
}
return children.size();
} @Override
public TreeNode getParent() { return parent;
}
@Override
public int getIndex(TreeNode aChild) { if (aChild == null) {
throw new IllegalArgumentException("argument is null");
} if (!isNodeChild(aChild)) {
return -1;
}
return children.indexOf(aChild);
} @Override
public boolean getAllowsChildren() { return true;
} /**
* 判断是否是叶子节点
*/
@Override
public boolean isLeaf() { return (getChildCount() ==-1)&&(getParent()!=null); } @SuppressWarnings("rawtypes")
@Override
public Enumeration children() {
return null;
} public boolean isNodeChild(TreeNode aNode) {
boolean retval; if (aNode == null) {
retval = false;
} else {
if (getChildCount() == 0) {
retval = false;
} else {
retval = (aNode.getParent() == this);
}
} return retval;
}
}

2.实现 TreeCellRenderer,这里要注意区分一下好友节点以及根节点,还有好友分组节点的显示是不一样的,需要分别考虑。同时在JLable中的text属性是不能换行的,所以使用了HTML来设置JLable的Text值。

public class FriTreeRender extends JLabel implements TreeCellRenderer {

	ImageIcon Arrow_right = new ImageIcon(this.getClass().getResource("Arrow_right.png"));//节点折叠时的图片
ImageIcon Arrow_down = new ImageIcon(this.getClass().getResource("Arrow_down.png"));//节点展开式的图片
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean
expanded,boolean leaf, int row, boolean hasFocus) {
FriTreeNode f = (FriTreeNode) value;//把value转换为节点
if (leaf && f.getParent() != tree.getModel().getRoot()) {//节点需要不为根节点,和根节点的孩子节点
/***************** 设置JLable的文字 ****************************/
String text = "<html>" + f.getuName() + "<br/>" + f.getText() + " <html/>";
setText(text);// 设置JLable的文字
/**************************** 设置JLable的图片 *****************/
// 得到此图标的 Image,然后创建此图像的缩放版本。
Image img = f.getImg().getImage().getScaledInstance(50, 50, Image.SCALE_DEFAULT);
setIcon(new ImageIcon(img));// 设置JLable的图片
setIconTextGap(15);// 设置JLable的图片与文字之间的距离
} else { // 非叶子节点的文字为节点的ID
setText(f.getID());// 设置JLable的文字
if (expanded)//节点展开
setIcon(Arrow_down);
else
setIcon(Arrow_right);// 设置JLable的图片
}
return this;
} }

3.然后就是和上面的实例一样去构建一个JTree了。

效果:

JTree实现QQ好友列表的更多相关文章

  1. iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)

    iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一) 一.项目结构和plist文件 二.实现代码 1.说明: 主控制器直接继承UITableViewController // ...

  2. [iOS基础控件 - 6.9.3] QQ好友列表Demo TableView

    A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组   code so ...

  3. 仿QQ好友列表界面的实现

    TableView有2种style:UITableViewStylePlain 和 UITableViewStyleGrouped. 但是QQ好友列表的tableView给人的感觉似乎是2个style ...

  4. ExpandableListView仿QQ好友列表

    本例中,对ExpandableListView中的数据进行了封装,分为两个JavaBean,一个为Group类表示组信息,一个Child类表示该组下子列表信息: Group: public class ...

  5. (二十七)QQ好友列表的实现

    QQ好友列表通过plist读取,plist的结构为一组字典,每个字典内有本组的信息和另外一组字典代表好友. 要读取plist,选择合适的数据结构,例如NSArray,然后调用initWithConte ...

  6. android 实现QQ好友列表

    在某些Android开发群里,看到有些新手问怎么实现QQ好友列表,其实网上一搜挺多的.接触Android,也才一年的时间,大部分时间花在工作上(解bug...),界面上开发很少参与.自己维护的系统应用 ...

  7. 基于Qt的相似QQ好友列表抽屉效果的实现

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shuideyidi/article/details/30619167     前段时间在忙毕业设计, ...

  8. swift 实现QQ好友列表功能

    最近项目中有类似QQ好友列表功能,整理了一下,话不多说,直接上代码 import UIKit class QQFriend: NSObject { var name: String? var intr ...

  9. Windows UIA自动化测试框架学习--获取qq好友列表

    前段时间应公司要求开发一款针对现有WPF程序的自动化测试工具,在网上查资料找了一段时间,发现用来做自动化测试的框架还是比较多的,比如python的两个模块pywinauto和uiautomation, ...

随机推荐

  1. java字符串MD5加密后再转16进制

    话不多说上码 pom.xml <!-- MD5 --> <dependency> <groupId>org.apache.commons</groupId&g ...

  2. Spring事务管理5-----声明式事务管理(3)

    声明式事务管理  基于注解 在配置文件中需要开启注解驱动<tx:annotation-driven transaction-manager="transactionManager&qu ...

  3. gitlab配置webhook报错解决

    https://blog.csdn.net/xukangkang1hao/article/details/80756085 gitlab使用webhook向jenkins发送请求,报错 Request ...

  4. 【文章存档】Local Git 如何部署分支

    又来存档文章了,链接 https://docs.azure.cn/zh-cn/articles/azure-operations-guide/app-service-web/aog-app-servi ...

  5. Windows下遍历所有GIT目录更新项目脚本

    将下面代码保存为.bat文件 @echo off set cdir=%~dp0 for /f "delims=" %%i in ('dir /ad/b/s "%cdir% ...

  6. vue项目中event bus的简单使用

    之前做的一个vue后台管理系统中,需要实现这样一个功能:从列表页点击新建或编辑进入新建.编辑页面,新建.编辑完成后需要关闭当前的新建和编辑tab,而tab的关闭则是由项目中的tag组件控制的, 新建和 ...

  7. 通用 spring cloud 微服务模板

    说明文档 功能 1. 基于映射数据库一键生成 spring cloud 微服务 2. 通用 Controller ,无需编写代码即可完成基于数据库的服务 3. 动态多条件 CRUD + 分页 使用说明 ...

  8. 《C程序设计语言》学习笔记

    1. 在C程序中,如果字符串过长而需要跨行时,要在换行时加上“\”. printf("Hello, world"); // error printf("Hello, wo ...

  9. 《你必须知道的495个C语言问题》读书笔记之第15-20章:浮点数、风格、杂项

    一.可变参数列表 1. Q:为什么调用printf前必须要包含<stdio.h>? A:为了把printf的正确原型说明引入作用域.例如,如果可变参数的调用比固定参数的调用效率低,编译器就 ...

  10. Spark的lazy特性有什么意义呢?

    [学习笔记] Spark通过lazy特性有什么意义呢? Spark通过lazy特性,可以进行底层的spark应用执行的优化.在生活中,就像三思而后行.谋定而后动. 文章转载自原文:https://bl ...