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" οnclick="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);