zoukankan      html  css  js  c++  java
  • JTree实现QQ好友列表

    最近学习了一下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了。

    效果:

  • 相关阅读:
    【模板】后缀自动机
    【模板】矩阵求逆
    【hdu5517】Triple
    【模板】多标记 LCT
    【洛谷P4172】水管局长
    【模板】LCT
    【CF786B】Legacy
    jacoco学习
    python + redis
    Python Gitlab Api 使用方法
  • 原文地址:https://www.cnblogs.com/hesi/p/6244819.html
Copyright © 2011-2022 走看看