Mindon.IDEA

Air off, Mind on ~ / Javascript+Golang, Sci, Health… /

Batik应用-在SVG中使用Java

BlogMS original blog key: 1000515173, blog id: airoff History stat: 浏览/评论:536/0 , 日期:2005年8月10日 11:02

在Batik中,支持SVG使用<script type="application/java-archive"/>来调用java,用法如:

<script type="application/java-archive" xlink:href="jevents.jar"/>

要求 jevents.jar 中的 manifest 必须包含如下信息

SVG-Handler-Class: classname

如:

SVG-Handle-Class: com.mindon.jevents.JEvents

我的JEvents采用了配置方式来实现灵活调用的目的。

1,在SVG采用不需进行渲染的元素<desc/>来配置我的Java事件。

如:

<desc id="jcalls">

<desc oid="myob1" method="test" params="23|34"/>

<desc oid="myob2" event="click" class="com.mindon.jevents.JETest" method="test"/>

</desc>

这样来实现在指定 object id 的元素的指定事件event上调用指定类class的公用静态方法method,并传递字符串参数数组(元素由|分隔)。

2,JEvents.java 实现

package com.mindon.jevents;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

import org.w3c.dom.Node;

import org.w3c.dom.events.Event;

import org.w3c.dom.events.EventListener;

import org.w3c.dom.events.EventTarget;

import java.lang.reflect.*;

public class JEvents implements org.w3c.dom.svg.EventListenerInitializer

{

public void initializeEventListeners(org.w3c.dom.svg.SVGDocument doc) {

// doc.createComment("from jevents");

Element jcalls = doc.getElementById("jcalls");

if(null != jcalls) {

NodeList jcnods = jcalls.getElementsByTagName("desc");

int kmax = jcnods.getLength();

String jcmname = null;

Method jcm = null;

String jccname = null;

Class jcc = null;

for(int k=0; k<kmax; k++) { // call definitions

Element jcall = (Element)jcnods.item(k);

String jcoid = jcall.getAttribute("oid");

EventTarget evtob = (EventTarget)doc.getElementById(jcoid);

if(null != evtob) { // object with oid exists

String evtname = jcall.getAttribute("event");

if(null==evtname || evtname.length() == 0) {

evtname = "click"; // default click event

}

try {

String method = jcall.getAttribute("method");

if(null!=method && method.length() > 0) { // method defined

String clsname = jcall.getAttribute("class");

boolean isnewc = false;

if(null == clsname || clsname.length() == 0) {

clsname = "com.mindon.jevents.JEvents"; // default class

}

if(!clsname.equals(jccname)) {

jcc = Class.forName(clsname);

isnewc = true;

}

if(null != jcc) { // class exists

if(!method.equals(jcmname) || isnewc) {

//System.out.println("[->>new method:" +clsname +"." +method);

jcm = jcc.getMethod(method, new Class[] {Element.class});

jcmname = method;

jccname = clsname;

}

if(null != jcm) { // method exists

String params = jcall.getAttribute("params");

if(null==params) params = "";

((Element)evtob).setAttribute("params", params);

final Method jmethod = jcm;

evtob.addEventListener(evtname, new EventListener() {

public void handleEvent(Event evt) {

try {

// method invoke

jmethod.invoke(null, new Object[] {evt.getTarget()});

} catch(Exception e) {

//System.out.println("[->>method");

//e.printStackTrace();

}

}

}, false);

}

}

} else {

System.out.println("[->>no method defined");

}

} catch(Exception e) {

System.out.println("[->>class or method exception");

//e.printStackTrace();

}

} else {

System.out.println("[->>object id=" +jcoid +" not found");

}

}

}

}

public static void test(Element target) {

System.out.println("test::<" +target.getNodeName() +" id=&quot;"

+target.getAttribute("id")

+"&quot;/>::" +target.getAttribute("params"));

}

}

这样,SVG文件中只要增加配置就可以像在 ECMAScript 中动态指定事件一样来指定某个元素对某个事件的响应,来执行指定的 Java 代码。这意味着在Batik应用开发使用的SVG事件可以响应任意的Java程序,而Java通过 JNI 则可以调用其他语言开发的动态库……

我的Batik应用环境是:J2SDK Standard Edition

Version 1.4.2 + Apache Ant version 1.6.1 + batik_all.jar(下载batik 1.6 的源码,用ant all-jar 编译生成)

Comments