svg桌面应用程序需要界面与后台的交互,当点击界面中一按钮时,需要后台java中处理事务,然后传回到界面中显示。
1.svg中js代码中运行java代码:
参考http://xmlgraphics.apache.org/batik/using/scripting/ecmascript.html
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> <circle cx="50" cy="50" r="50" fill="green" onclick="showFrame()"/> <script type="text/ecmascript"> importPackage(Packages.javax.swing); function showFrame() { var frame = new JFrame("My test frame"); var label = new JLabel("Hello from Java objects created in ECMAScript!"); label.setHorizontalAlignment(SwingConstants.CENTER); frame.getContentPane().add(label); frame.setSize(400, 100); frame.setVisible(true); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); } </script> </svg>
importPackage(Packages.javax.swing); 引入java.swing包
JFrame是一个java类,以上是script代码中用JFrame弹出一个窗体。
2. java控制svg-script
canvas.getUpdateManager().getScriptingEnvironment().getInterpreter().evaluate(String param);
canvas为JSVGCanvas实例
param为script表达式,如alert('a'), func('','','')
evaluate相于中js 中eval方法。
个人认为以上方法的控制效果并不理想,如当要定时去改变svg的某元素状态时,经常出现黑区域和闪烁现象,而且界面也常弹出错误框,而在script代码中定时改变状态时,则不会出现此种情况。 由于script中可以访问java空间,所以我们可以在java空间加入一系列的任务,而script则定时去访问这个任务列表,取出这些任务,然后执行,删除任务。
任务列表SVGJs.java
public static Queue<String> tasks = new ConcurrentLinkedQueue<String>();
java中pushTask,将script要调用的方法,参数存储起来。
public static String popTask(){ synchronized(tasks){ return tasks.poll(); } } public static void pushTask(String t){ synchronized(tasks){ tasks.add(t); } }
svg-script中取出任务,然后执行
function callFunc(){ var task = SVGJs.popTask(); while(task!=null) { eval(task); task = SVGJs.popTask(); } }
可用setTimeout设置callFunc定时运行。
eg1.使用第一种方法java直接调用script
package com.longshine.svg.ui; import java.awt.Color; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import javax.swing.JFrame; import org.apache.batik.dom.svg.SAXSVGDocumentFactory; import org.apache.batik.swing.JSVGCanvas; import org.apache.batik.util.XMLResourceDescriptor; import org.w3c.dom.Document; public class SVGUIApp extends JFrame{ public void init(){ this.setBounds(0, 0, 800, 600); this.setDefaultCloseOperation(3); this.setVisible(true); String parser = XMLResourceDescriptor.getXMLParserClassName(); SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); File file = new File("bin/com/longshine/svg/ui/3D.svg"); try { Document indexDoc = f.createDocument(file.toURL().toString()); JSVGCanvas canvas = new JSVGCanvas(); canvas.setBackground(Color.BLACK); canvas.setVisible(true); canvas.setBounds(0, 0, 800, 600); canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); canvas.setDocument(indexDoc); this.add(canvas); Thread.sleep(5000); canvas.getUpdateManager().getScriptingEnvironment().getInterpreter().evaluate("test()");//*************调用script中test******************** } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args){ new SVGUIApp().init(); } }
图一.java调用script test()方法
script中调用java 中println方法
importPackage(Packages.com.longshine.svg.ui); SVGJs.println("call java function");
package com.longshine.svg.ui; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class SVGJs { public static void println(Object o){ System.out.println(o); } }
eg2.java间接调用,实现 图一效果
package com.longshine.svg.ui; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class SVGJs { public static Queue<String> tasks = new ConcurrentLinkedQueue<String>();//任务列表 public static String popTask(){//取出任务 synchronized(tasks){ return tasks.poll(); } } public static void pushTask(String t){//加入任务 synchronized(tasks){ tasks.add(t); } } public static void println(Object o){ System.out.println(o); } }
package com.longshine.svg.ui; import java.awt.Color; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import javax.swing.JFrame; import org.apache.batik.dom.svg.SAXSVGDocumentFactory; import org.apache.batik.swing.JSVGCanvas; import org.apache.batik.util.XMLResourceDescriptor; import org.w3c.dom.Document; public class SVGUIApp extends JFrame{ public void init(){ this.setBounds(0, 0, 800, 600); this.setDefaultCloseOperation(3); this.setVisible(true); String parser = XMLResourceDescriptor.getXMLParserClassName(); SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser); File file = new File("bin/com/longshine/svg/ui/3D.svg"); try { Document indexDoc = f.createDocument(file.toURL().toString()); JSVGCanvas canvas = new JSVGCanvas(); canvas.setBackground(Color.BLACK); canvas.setVisible(true); canvas.setBounds(0, 0, 800, 600); canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC); canvas.setDocument(indexDoc); this.add(canvas); Thread.sleep(5000); // canvas.getUpdateManager().getScriptingEnvironment().getInterpreter().evaluate("test()"); SVGJs.pushTask("test()");//间接调用 } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args){ new SVGUIApp().init(); } }
function callFunc(){ var task = SVGJs.popTask(); while(task!=null) { eval(task); task = SVGJs.popTask(); } setTimeout('callFunc()',500); } callFunc();//定时从java SVGJs类中取出任务执行
question: 有时svg 程序运行cpu占用一个核,单核使用率100%,双核50%,4核25%.
需限制svg cpu使用:
canvas.setAnimationLimitingCPU(float);