[Embed(source="/demo/images/equipments/cisco3600.png")] public static const cisco3600:Class; Utils.registerImageByClass("cisco3600", cisco3600); node.image = cisco3600;
使用TWaver Flex的客户肯定很羡慕使用TWaver Java可以通过node.setImage(“/demo/images/equipments/cisco3600.png”);就可以直接设置图片在jar包中的路径,用不着像以上Flex代码那样需要定义Embed类且注册后才能使用。
不过注册也有注册的好处,例如上面的cisco3600.png如果将来改成cisco3600.jpg或者图片路径变化,那么你还得到处改代码,而采用注册的方式node上的image永远只要保留最简单的不易改变的标示“cisco3600”,因此TWaver Java也有TWaverUtil.registerImageIcon(String url, ImageIcon imageIcon)的功能。
说过题外话曾经有个客户已经将/com/company/AAA/equipment.png路径的图元信息将拓扑图存储成了xml,并已经存到后台数据库,结果后来项目重构将AAA的目录名称改成了BBB,结果发现所有拓扑图读取图片都出问题了,如果他们采用注册的方式可能可以选择不易更改的名字也就没这问题,但TWaver总是会考虑到几百上千家不同客户的不同用法可能导致的各种千奇百怪的问题,刚开始用户以后这个问题将是灾难性的了,后来咨询我了解到TWaver还有ResourceLocateInterceptor拦截器可以进行扩展,而无需改动后台数据库已存的几百种设备拓扑图后感动得….
TWaverUtil.setResourceLocateInterceptor(new ResourceLocateInterceptor(){ public Object locate(String url){ if(url.startWith("/com/company/AAA/")){ return url.replaceAll("/com/company/AAA/", "/com/company/BBB/"); } return null; } });
/* * This source code is part of TWaver 3.5 * * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * Copyright 2010 Serva Software. All rights reserved. */ package twaver; /** * This interceptor can be implemneted to customize * resolving resource location for xml, image, etc. * * @see twaver.TWaverUtil#setResourceLocateInterceptor */ public interface ResourceLocateInterceptor extends Interceptor{ /** * This is used to indicate invalid url. */ public final static Object INVALID_URL = new Object(); /** * Locates resource with the specified url. * @param url the url of resource that needs to be located. * @return * if java.io.InputStream is returned, twaver will * use the return inputStream to read resource data. * * if String is returned, twaver will use the new url * to locate resource by the default resolving mechanism. * * if #INVALID_URL is returned, twaver will treat the url * as invalid url and will not resolving location any more. * * if null or else value is returned, twaver will ignore * the return value to locate resource by default resolving * mechanism with the default specified url. */ public Object locate(String url); }
回到今天的话题,TWaver Flex虽然不支持不注册就能访问swc中资源图片的功能,但还是运行动态访问swc之外可以范围的任何图元资源,最常见的就是HTTP的后台图片方式,例如你可以直接设置node.image = “http://www.servasoftware.com/images/cp_twaver.png”,twaver如果发现image的内容不是已经注册的就会尝试将你设置的image作为一个url去动态下载资源,对Flex有经验的开发者会想到flex加载图片是异步的,twaver加载完图片后我如何知道,然后我如何更新界面,答案是你可以通过Utils.addImageLoadedListener监听到twaver的加载成功事件,但大部分情况下你不用做任何监听,twaver加载完毕后会自动更新所有和该elmenet关联的databox,同时更新所有和该box绑定的tree、table和network等组件,可以说TWaver Flex尽力做到让你感觉和用TWaver Java一样容易轻松。
我还遇到过一个辽宁移动的客户要求在后台图片找不到时显示个默认指定的图片,当然这个功能不借助TWaver也可以从后台实现,例如设置个Filter的拦截器,当访问的图片资源找不着时将其redirect到另外一个指定的url,不过这毕竟需要后台的代码和设置,远不如通过自定twaver.Defaults.LOAD_IMAGE_ERROR_FUNCTION的处理功能来得方便简单,例如你可以自定义个直接返回一个指定的BitmapData就解决了,甚至还可以加些逻辑处理,例如不同类型的name(其实这里就是http的url)返回不同类型的指定图片,以下twaver内部实现代码大家可以参考,这种通过f.length动态判断函数参数还是as和js这种动态语言常用的且非常灵活实用的技巧
private static function handleError(e:Event, name:String):void{ var f:Function = twaver.Defaults.LOAD_IMAGE_ERROR_FUNCTION; if(f != null){ var returnValue:*; if(f.length == 0){ returnValue = f(); } else if(f.length == 1){ returnValue = f(e); } else if(f.length == 2){ returnValue = f(e, name); } if(returnValue is BitmapData){ var imageAsset:IImageAsset = new ImageAsset(returnValue as BitmapData); ImageUtils.register(name, imageAsset); dispatcher.dispatchEvent(new ImageLoadEvent(name, imageAsset)); } } }
以下这个小例子大家可以跑跑玩玩