`

ASwing 中 JTree 实现 folder 自定义图标

阅读更多

最近在用 ASwing 做项目,需要根据节点内容自定义 folder 的图标。网上找到一些例子但总有各种各样的问题,于是通过查看 ASwing 的代码,实现了这个简单的功能。在这里跟大家分享,也记录一下比较容易错的几个点。

 

首先说一下ASwing渲染的结构。



 

大概的结构就是这样,最后每个节点的渲染是在 TreeCell 中提供图标的。所以实现功能只需要自定义一个自己的 TreeCell 子类。下面是代码:

package {
	import org.aswing.Icon;
	import org.aswing.tree.DefaultTreeCell;
	import org.aswing.tree.MutableTreeNode;
	
	/**
	 * @author dengyang
	 */
	public class MyTreeCell extends DefaultTreeCell{
	
		private var squareIcon:Icon;
		private var dotIcon:Icon;
		
		public function MyTreeCell(){
			super();
			if(squareIcon == null) {
				squareIcon = new SquareIcon();
			}
			if(dotIcon == null) {
				dotIcon = new DotIcon();
			}
		}
			
		override public function setCellValue(value:*) : void {
			super.setCellValue(value);
			//根据此Cell的值,如果最后一个字符数字是偶数,则使用方形图标
			//否则使用圆形图标
			var node:MutableTreeNode = MutableTreeNode(value);
			var str:String = node.getUserObject();
			if(str == '德州扑克'){
				expanded_folder_icon = dotIcon;
				collapsed_folder_icon = dotIcon;
			}else{
				expanded_folder_icon = squareIcon;
				collapsed_folder_icon = squareIcon;
			}
		}	
	}
}

import org.aswing.ASColor;
import org.aswing.Component;
import org.aswing.Icon;
import org.aswing.graphics.Graphics2D;
import org.aswing.graphics.SolidBrush;

import flash.display.DisplayObject;
import flash.display.Sprite;

class SquareIcon implements Icon{
	
	[Embed(source="dz.png")]
	private var dzpng : Class;
	private var dzIcon : DisplayObject;
	
	public function SquareIcon(){
		if(dzIcon == null) {
			dzIcon = new dzpng();
		}
	}
	
	public function getIconWidth(c:Component):int{
		return 16;
	}
	
	public function getIconHeight(c:Component):int{
		return 16;
	}
	
	public function updateIcon(c:Component, g:Graphics2D, x:int, y:int):void{
		g.fillRectangle(new SolidBrush(ASColor.GREEN), x, y, 12, 12);
	}
	
	public function getDisplay(c:Component):DisplayObject{
		return dzIcon;
	}
}


class DotIcon implements Icon{
	
	[Embed(source="dz.png")]
	private var dzpng : Class;
	
	[Embed(source="lock.png")]
	private var lockPng : Class;
	
	private var dzIcon : Sprite;
	
	public function DotIcon(){
		if(dzIcon == null) {
			dzIcon = new Sprite();
			dzIcon.addChild(new dzpng());
			dzIcon.addChild(new lockPng());
		}
	}
	
	public function getIconWidth(c:Component):int{
		return 16;
	}
	
	public function getIconHeight(c:Component):int{
		return 16;
	}
	
	public function updateIcon(c:Component, g:Graphics2D, x:int, y:int):void{
		g.fillCircle(new SolidBrush(ASColor.RED), x+6, y+6, 6);
	}
	
	public function getDisplay(c:Component):DisplayObject{
		return dzIcon;
	}
}

 

代码很简单,但却很容易错。我就错了两次。

起初我在每一个 getDisplay() 中都 new Icon(),造成树上的图标会有残影;后来我在 getDisplay() 中返回 static 的 Icon,同类图表中只有最后一个显示。

 

后来看了一下 DefaultTreeCell 父类 JLabel 中的 setIcon() ,其中有两个操作,一个是 uninstallIcon ,一个是 installIcon。如果每次都 new 新的对象会造成 uninstallIcon 中无法 remove 上次加载的 icon。而如果是静态变量的话,又会造成每次加入新的 Cell 时会把原有 icon remove 掉。

 

我知道说起来好像很理所当然,不过在没看代码的前提下还是很容易错的。所以在此记录一下。

  • 大小: 28 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics