- 浏览: 28951 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
mysh:
zoel175185 写道请问 可不可以添加一个功能 就是在启 ...
代码片段管理工具 - CodeLib2 b6150 -
zoel175185:
请问 可不可以添加一个功能 就是在启动的 时候默认打开一个 数 ...
代码片段管理工具 - CodeLib2 b6150 -
maofan3000:
不知道swfobject需要下载什么版本?
zk 与 flash 交互 - FlashContainer -
maofan3000:
我拿你的例子,怎么也不出效果,您能把你的文件打包下载吗?
zk 与 flash 交互 - FlashContainer -
mysh:
mazhiyuan 写道请问哪里用到了JDK7的特性,我之前也 ...
代码片段管理工具 - CodeLib2 b6150
前阵子搞 zk 与 flash 交互,搞得头破血流,zk 本身带有 flash 标签,但只能当播放器用,没法进行比较复杂的 flash 控制,如调用 flash 的内部方法。flash 也没法直接通过前端与 zk 组件交互,于是自己搞了一个中间件,用于 zk 与 flash 的交互,使得 zk 可以直接调用 flash 的内部方法,flash 可以直接向 zk 发送数据,同时加入了一点同步控制,因为 flash 虚拟机是异步单线程的,且 zk 的每个 flash 调用都是独立的,在实际执行过程中无法保证调用顺序。
需要 zk 5.0 以上版本,flash 支持 flex sdk3 和 sdk4 编译程序。
demo.zul(zk 演示页面)
<?page title="demoZK" contentType="text/html;charset=UTF-8"?> <zk> <window title="demoZK" border="normal" width="100%" height="100%" apply="mysh.Demo"> <div id="flashDiv" /> </window> </zk>
Demo.java(zk 端演示组件)
package mysh; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.util.GenericComposer; import org.zkoss.zul.Div; import org.zkoss.zul.Messagebox; import mysh.FlashContainer; /** * Demo. * * @version Revision 1.0.0 */ public class Demo extends GenericComposer { /* * @see org.zkoss.zk.ui.ext.AfterCompose#afterCompose() */ @Override public void doAfterCompose(Component comp) { Div flashDiv = (Div) comp.getFellow("flashDiv"); flashDiv.addEventListener(FlashContainer.ON_CONTAINER_INFO, new EventListener() { public void onEvent(Event event) throws Exception { Messagebox.show("receive from flash : " + event.getData(), "zk msg", Messagebox.OK, Messagebox.INFORMATION); } }); FlashContainer flashContainer = FlashContainer.genFlashContainer( flashDiv, "demoFlash.swf"); flashContainer.registObserver(flashDiv); flashContainer.callFlash("func1", "param"); } }
demoFlash. mxml(flash 端演示)
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" applicationComplete="init()" xmlns:mx="library://ns.adobe.com/flex/mx" width="594" height="416"> <fx:Script> <![CDATA[ import mysh.FlashContainer; import mx.controls.Alert; private var flashContainer:FlashContainer; private function init():void { this.flashContainer=new FlashContainer(this); this.flashContainer.registFunc("func1", this.function1); } private function function1(param:String):void { Alert.show("msg from zk : " + param); } protected function send2ZK_clickHandler(event:MouseEvent):void { this.flashContainer.sendEvent2ZK(this.input.text); } ]]> </fx:Script> <s:Button id="send2ZK" x="46" y="101" label="发送到 zk" click="send2ZK_clickHandler(event)"/> <s:TextInput id="input" x="45" y="56"/> </s:Application>
flashContainer.as(flash 端组件。D.eval 下载地址)
package mysh
{ import flash.external.ExternalInterface; import mx.controls.Alert; import mx.core.Application; import r1.deval.D; /** * flash 容器 * * @version 20110117 */ public class FlashContainer { /** * 容器持有者 */ private var holder:Object; /** * 发送事件调用的JS方法 */ private var eventSendFunc:String; /** * 所有注册方法 */ private var funcs:Object=new Object(); /** * 执行顺序 */ private var order:Number=0; public function FlashContainer(holder:Object) { this.holder=holder; // sdk3 : this.eventSendFunc=Application.application.parameters.eventFunc; // sdk4 : // this.eventSendFunc=FlexGlobals.topLevelApplication.parameters.eventFunc; ExternalInterface.addCallback("jsCall", jsCall); } /** * 外部js调用的方法 */ private function jsCall(jsonStr:String):void { // Alert.show(jsonStr); var jsonObj:Object=D.eval(jsonStr); var funcArray:Array=jsonObj.funcs as Array; var order:Number=jsonObj.order as Number; // 检查执行顺序,若 小于0,则执行;若 大于0,则只有 大于 this.order 才执行 if (order > 0) { if (order > this.order) { this.order=order; } else { return; } } // Alert.show(order+","+this.order); for each (var pack:Object in funcArray) { var func:String=pack.func; var args:Array=pack.args; var treatedArgs:Array=new Array(); for (var i:int=0; i < args.length; i++) { treatedArgs[i]=(args[i] as String).replace(/"/g, "\"").replace(/'/g, "'"); } if (this.funcs[func] == null) { Alert.show("FlashContainer 找不到方法:" + func, "内部错误"); return; } (this.funcs[func] as Function).apply(this.holder, treatedArgs); } } /** * 注册方法名 * @param func 方法名 * @param method 方法实体 */ public function registFunc(func:String, method:Function):void { if (func == null || func == "" || method == null) { throw new Error("方法名或方法不能为空"); } this.funcs[func]=method; } /** * 发送事件到 zk * @param value 值 */ public function sendEvent2ZK(value:String):void { // Alert.show(this.eventSendFunc); ExternalInterface.call(this.eventSendFunc, value); } } }
flashContainer.zul(zk 页面)
<?page title="" contentType="text/html;charset=UTF-8"?> <zk> <window title="" border="normal" use="FlashContainer"> </window> </zk>
FlashContainer.java(zk端组件。swfobject.js 下载地址。随着功能的增加,我觉得叫 FlashManager 比较合适)
import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.concurrent.atomic.AtomicLong; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Div; import org.zkoss.zul.Script; import org.zkoss.zul.Window; /** * flash容器. * 非线程安全,需要外部同步. * * @version 20110117 */ public final class FlashContainer extends Window implements AfterCompose { /** * serialVersionUID. */ private static final long serialVersionUID = 2564493195082621543L; /** * zul 页面地址. */ private static final String ZUL_PATH = "flashContainer.zul"; /** * 方法调用定义. * * @version Revision 1.0.0 */ public static final class FlashFuncInvoke { /** * 方法名. */ private String func; /** * 方法参数. */ private String[] args; /** * 构造器. * * @param tFunc * 方法名 * @param tArgs * 方法参数 */ public FlashFuncInvoke(String tFunc, String... tArgs) { if (tFunc == null || tFunc.length() == 0 || tArgs == null) { throw new RuntimeException("非法参数"); } this.func = tFunc; this.args = tArgs; } /** * 返回一个“单元素列表”. * * @param tFunc * 方法名 * @param tArgs * 方法参数 * @return 单元素列表 */ public static List<FlashFuncInvoke> genSingleEleList(String tFunc, String... tArgs) { List<FlashFuncInvoke> funcList = new ArrayList<FlashContainer.FlashFuncInvoke>( 1); funcList.add(new FlashFuncInvoke(tFunc, tArgs)); return Collections.unmodifiableList(funcList); } } /** * 用于浏览器端向服务端发送事件. */ private static final String ON_CIENT_INFO = "onClientInfo"; /** * flash 容器事件的名称,用于取得此容器发送的事件(从客户端取得的事件). */ public static final String ON_CONTAINER_INFO = "onContainerInfo"; /** * 执行顺序号限制(2^52-1). */ private static final long ORDER_LIMIT = 0xFFFFFFFFFFFFFL; /** * 执行顺序号生成器. */ private final AtomicLong orderGen = new AtomicLong(1L); /** * 事件监听组件. */ private Div eventListener = new Div(); /** * flash 容器. */ private Div flash = new Div(); /** * 浏览器端脚本容器. */ private Script script = new Script(); /** * 浏览器 js 方法命名空间. */ private String ns; /** * flash动作观察者. */ private Queue<Component> observers = new LinkedList<Component>(); /** * 生成 FlashContainer(用于 flash 9 版本). * * @param parent * flash容器的父组件 * @param swfSrc * 页面 js 可访问的 swf 路径 * @return FlashContainer */ public static FlashContainer genFlashContainer(Component parent, String swfSrc) { Map<String, String> args = new HashMap<String, String>(); args.put("flashSrc", swfSrc); args.put("flashVer", "9"); return (FlashContainer) Executions.createComponents( FlashContainer.ZUL_PATH, parent, args); } /** * 生成 FlashContainer(用于 flash 10 版本). * * @param parent * flash容器的父组件 * @param swfSrc * 页面 js 可访问的 swf 路径 * @return FlashContainer */ public static FlashContainer genFlashContainerVer10(Component parent, String swfSrc) { Map<String, String> args = new HashMap<String, String>(); args.put("flashSrc", swfSrc); args.put("flashVer", "10"); return (FlashContainer) Executions.createComponents( FlashContainer.ZUL_PATH, parent, args); } /** * 生成 FlashContainer(用于 flash 10 版本). * * @param parent * flash容器的父组件 * @param swfSrc * 页面 js 可访问的 swf 路径 * @param flashVars * 传递给 flash 的参数 * @return FlashContainer */ public static FlashContainer genFlashContainerVer10(Component parent, String swfSrc, Map<String, String> flashVars) { Map<String, Object> args = new HashMap<String, Object>(); args.put("flashSrc", swfSrc); args.put("flashVer", "10"); args.put("flashVars", flashVars); return (FlashContainer) Executions.createComponents( FlashContainer.ZUL_PATH, parent, args); } /** * 构造器. */ public FlashContainer() { this.ns = this.getUuid(); this.appendChild(this.eventListener); this.appendChild(this.flash); this.appendChild(this.script); this.eventListener.addEventListener(FlashContainer.ON_CIENT_INFO, new EventListener() { @Override public void onEvent(Event event) throws Exception { // flash 控件不支持,打开下载页面 if (event.getData().equals("flashNotSupported")) { alert("flashNotSupported"); } for (Component comp : FlashContainer.this.observers) { Event e = new Event(FlashContainer.ON_CONTAINER_INFO, comp, event.getData()); Events.sendEvent(e); } } }); // 发送事件脚本 String scriptStr = "function " + this.ns + "_flashSend(v){var e = new zk.Event();e.$init(zk.Widget.$('" + this.eventListener.getUuid() + "'), '" + FlashContainer.ON_CIENT_INFO + "', v);zAu.send(e);}"; // 调用 flash 方法 scriptStr += "function " + this.ns + "_callFlash(jsonStr){" + "var flash=null;try{flash = document.getElementById(\"" + this.flash.getUuid() + "\").jsCall(jsonStr);}catch(err){setTimeout(\"" + this.ns + "_callFlash('\"+jsonStr+\"')\",150);}}"; this.script.setContent(scriptStr); // swfobject Script swfobject = new Script(); swfobject.setSrc("/common/js/swfobject.js"); this.appendChild(swfobject); } /* * @see org.zkoss.zk.ui.ext.AfterCompose#afterCompose() */ @SuppressWarnings("unchecked") @Override public void afterCompose() { // javaScript 可识别的 swf 地址 String flashSrc = (String) Executions.getCurrent().getArg() .get("flashSrc"); // flash 播放需要的播放器版本号 String flashVer = (String) Executions.getCurrent().getArg() .get("flashVer"); // 传递给 flash 的参数 Map<String, String> flashVars = (Map<String, String>) Executions .getCurrent().getArg().get("flashVars"); String detectFlashVer = "9,0,124"; String swfobjectFlashVer = "9.0.124"; if (flashVer != null && flashVer.equals("10")) { detectFlashVer = "10,0,0"; swfobjectFlashVer = "10.0.0"; } // 检查 flash 控件版本,若不支持给定的 flash 版本,弹出页面 Clients.evalJavaScript("if(!DetectFlashVer(" + detectFlashVer + ")){" + this.ns + "_flashSend('flashNotSupported');}"); // 初始化flash,传入 js发送事件方法名 Clients.evalJavaScript("function " + this.ns + "_initSWF(){try{swfobject.embedSWF('" + flashSrc + "', '" + this.flash.getUuid() + "', '100%', '100%', '" + swfobjectFlashVer + "', '', {eventFunc:'" + this.ns + "_flashSend'" + this.genFlashVars(flashVars) + "}, {wmode:'opaque'}, {});}catch(e){setTimeout('" + this.ns + "_initSWF();',100);}}" + this.ns + "_initSWF();"); } /** * 生成 flashvars 参数字串.<br/> * 若参数为 null,则生成的参数为 ''<br/> * 参数名为空的参数将被忽略;含有引号的参数为非法参数,将抛运行时异常<br/> * 格式:,a:'a',b:'b' * * @param flashVars * 参数 map * @return 参数字串 */ private String genFlashVars(Map<String, String> flashVars) { if (flashVars == null) { return ""; } StringBuilder vars = new StringBuilder(""); String tempKey, tempValue; for (Map.Entry<String, String> entry : flashVars.entrySet()) { tempKey = entry.getKey(); if (tempKey == null || tempKey.length() == 0) { continue; } tempValue = entry.getValue(); if (tempValue == null || tempValue.contains("\'") || tempValue.contains("\"")) { throw new RuntimeException("非法参数:" + tempValue); } vars.append(","); vars.append(tempKey); vars.append(":'"); vars.append(tempValue); vars.append("'"); } return vars.toString(); } /** * 只执行最新的调用(以调用顺序为准),忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/> * 此方法用于解决对 flash 端的多个调用不能保证顺序的问题. <br/> * 若不希望任何调用被忽略,请用 callFlashFuncList 方法. <br/> * 调用flash方法. * * @param func * flash 方法名 * @param args * 可变参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常) */ public void callFlashLatest(String func, String... args) { this.innerCallFlashFuncList(this.orderGen.incrementAndGet(), FlashFuncInvoke.genSingleEleList(func, args)); } /** * 调用flash方法. 这个方法的多个调用在 flash 客户端不能保证调用顺序. <br/> * 要确保调用顺序,尝试 callFlashLatest 或 callFlashFuncList 方法. <br/> * * @param func * flash 方法名 * @param args * 可变参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常) */ public void callFlash(String func, String... args) { this.innerCallFlashFuncList(-1L, FlashFuncInvoke.genSingleEleList(func, args)); } /** * 只执行最新的调用(以调用顺序为准),忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/> * 此方法用于解决对 flash 端的多个调用不能保证顺序的问题. <br/> * 按顺序执行给定的 flash 方法. <br/> * 方法参数中不允许含有 &quot; 或 &apos;,有则抛异常 * * @param list * 方法定义列表 */ public void callFlashFuncListLatest(List<FlashFuncInvoke> list) { this.innerCallFlashFuncList(this.orderGen.incrementAndGet(), list); } /** * 按顺序执行给定的 flash 方法. 这个方法的多个调用在 flash 客户端不能保证调用顺序. <br/> * 要确保调用顺序,尝试 callFlashFuncListLatest 方法. <br/> * 方法参数中不允许含有 &quot; 或 &apos;,有则抛异常 * * @param list * 方法定义列表 */ public void callFlashFuncList(List<FlashFuncInvoke> list) { this.innerCallFlashFuncList(-1L, list); } /** * 向 flash 客户端发送执行命令(方法调用). * * @param order * 给定一个执行顺序值(一个从小到大的正值,不能大于 2^52-1=4503599627370495L. <br/> * 若为 -1L,则 flash 端执行此调用;若为一个正值,则 flash * 端将忽略旧的调用(执行顺序值小于客户端当前执行顺序值的调用). <br/> * 给定执行顺序值用于解决这样一个问题:flash 客户端的多个调用的执行不能同步,但给定执行顺序将导致旧的调用被忽略 * @param list * 方法定义列表 */ private void innerCallFlashFuncList(long order, List<FlashFuncInvoke> list) { if (order < -1L || order > FlashContainer.ORDER_LIMIT) { throw new RuntimeException("执行顺序值超出 [-1, 2^52-1]"); } if (list == null || list.size() < 1) { return; } StringBuilder str = new StringBuilder("var j={order:"); str.append(order); str.append(",funcs:["); for (FlashFuncInvoke funcInvoke : list) { str.append(this.genJsonString(funcInvoke.func, funcInvoke.args)); str.append(","); } if (str.charAt(str.length() - 1) == ',') { str.deleteCharAt(str.length() - 1); } str.append("]}"); Clients.evalJavaScript(this.ns + "_callFlash(\'" + str.toString() + "\')"); } /** * 根据给定的方法名、方法参数生成 json 对象字符串. * * @param func * 方法名 * @param args * 方法参数(参数中不允许含有 &quot; 或 &apos;,有则抛异常) * @return json 对象字符串 */ private String genJsonString(String func, String[] args) { String argsStr = ""; if (args != null && args.length != 0) { for (String arg : args) { if (arg == null) { throw new RuntimeException("不允许 null 值作为参数"); } if (arg.contains(""") || arg.contains("'")) { throw new RuntimeException("参数中不允许含有 " 或 '"); } argsStr += "\"" + arg.replace("\"", """).replace("'", "'") + "\","; } argsStr = argsStr.substring(0, argsStr.length() - 1); } return "{func:\"" + func + "\", args:[" + argsStr + "]}"; } /** * 注册一个 flash 事件观察者. * 该观察者需要注册 ON_CONTAINER_INFO 的事件监听 * * @param observer * flash 动作观察者 */ public void registObserver(Component observer) { this.observers.add(observer); } }
评论
2 楼
maofan3000
2013-08-12
不知道swfobject需要下载什么版本?
1 楼
maofan3000
2013-08-12
我拿你的例子,怎么也不出效果,您能把你的文件打包下载吗?
相关推荐
SMC ZK2-ZSEA-A设置方法
中控智慧设备说明书
幸福象花一样 ZKZK REMIX_2---02.flp
Zk的相关需要的类包和开发环境,请参考学习
zk source code http://www.zkoss.org/javadoc/latest/zk/
一个zk的demo,主要方面的信息,大家下载完以后就知道了 呵呵
ZK Spreadsheet(3-1)
zk-6.5.0.zip ZK 6.5.0 Sep 12, 2012 * Features ZK-447: The file upload allows users to drag and drop local files (HTML5) ZK-1241: ZK Client Widget support swipe event for tablet/mobile device ZK-...
ZK剂量仪系列-ermes-electronics.pdf
zk-Gmaps-src-2.0_10.zip zk-Gmaps-src-2.0_10.zip
建筑工程常用表格2021C22-6-3_世纪大道工业供水(ZK2+000-ZK3+000).xls
建筑工程常用表格2021C22-6-3_世纪大道工业供水(ZK1+154-ZK2+000).xls
ZK 8.0.0端参考 ZK 8.0.0组件开发的必需品 ZK 8.0.0组件引用 ZK 8.0.0配置参考 ZK 8.0.0开发人员的参考 ZK 8.0.0风格定制指南 ZK 8.0.0 ZUML参考 zk-mvvm-book
建筑工程常用表格2021C22-6-1_世纪大道(ZK1+154-ZK2+000)给水管道安装.xls
建筑工程常用表格2021C22-6-1_世纪大道工业供水(ZK2+000-ZK3+000)给水管道安装.xls
zk-src-3.0.3-2008-01-31
TPC-ZK-II微机接口实验系统正是在这种背景下推出的,该设备在TPC-ZK-II微机接口实验系统上配置了USB接口模块,直接与主机(PC)的USB接口连接,形成了一套完整的USB总线接口的微机接口实验系统。
zk.part3.rar(3-3)
zk.part2.rar(3-2)
zk-src-5.0.7.1(zk源码)呗