`
yydcj
  • 浏览: 61534 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使用Batik创建SVG应用程序(二)

    博客分类:
  • SVG
阅读更多

引自http://blog.csdn.net/firefight/archive/2007/02/06/1503103.aspx

使用 Batik 创建 SVG 应用程序

Batik 工具集提供的 JSVGCanvas 模块是一个 swing 组件,用于显示静态或动态 SVG 文档。通过 JSVGCanvas 模块,开发人员可以轻松显示 SVG 文档(通过 URI 地址或 DOM 树)并对其进行操作,例如旋转、缩放、摇动、选择文本或激活超级链接等。首先介绍如何创建 JSVGCanvas 并集成到一个 swing 应用程序中。接下来解释如何完成与 SVG 画布相关的常用功能,例如如何跟踪 SVG 文档渲染时发生的所有事件,以及如何通过 JavaTM 语言操作 SVG 文档。

创建 JSVGCanvas

JSVGCanvas 是一个 swing 组件并遵循 swing 设计规则 (Swing design rule [4] ) 。这意味着组件不是线程安全的,而且所有操作应当参照 swing 教程描述使用。 JSVGCanvas 也是一个 JavaBean 组件,因此可以在可视化应用程序开发工具中使用。下例中演示了如何轻松创建和使用 JSVGCanvas 组件(见图 3 )。

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import javax.swing.*;

 

import org.apache.batik.swing.JSVGCanvas;

import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;

import org.apache.batik.swing.gvt.GVTTreeRendererEvent;

import org.apache.batik.swing.svg.SVGDocumentLoaderAdapter;

import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;

import org.apache.batik.swing.svg.GVTTreeBuilderAdapter;

import org.apache.batik.swing.svg.GVTTreeBuilderEvent;

 

public class SVGApplication {

 

    public static void main(String[] args) {

        JFrame f = new JFrame("Batik");

        SVGApplication app = new SVGApplication(f);

        f.getContentPane().add(app.createComponents());

        f.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

                System.exit(0);

            }

        });

        f.setSize(400, 400);

        f.setVisible(true);

    }

   

    JFrame frame;

    JButton button = new JButton("Load...");

    JLabel label = new JLabel();

    JSVGCanvas svgCanvas = new JSVGCanvas();

 

    public SVGApplication(JFrame f) {

        frame = f;

    }

 

    public JComponent createComponents() {

        final JPanel panel = new JPanel(new BorderLayout());

        JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));

        p.add(button);

        p.add(label);

        panel.add(p, BorderLayout.NORTH);

        panel.add(svgCanvas, BorderLayout.CENTER);

 

        // Set the button action.

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent ae) {

                JFileChooser fc = new JFileChooser(".");

                int choice = fc.showOpenDialog(panel);

                if (choice == JFileChooser.APPROVE_OPTION) {

                    File f = fc.getSelectedFile();

                    try {

                        svgCanvas.setURI(f.toURL().toString());

                    } catch (IOException ex) {

                        ex.printStackTrace();

                    }

                }

            }

        });

 

        // Set the JSVGCanvas listeners.

        svgCanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter() {

             public void documentLoadingStarted(SVGDocumentLoaderEvent e) {

                label.setText("Document Loading...");

            }

            public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {

                label.setText("Document Loaded.");

            }

        });

 

        svgCanvas.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {

            public void gvtBuildStarted(GVTTreeBuilderEvent e) {

                label.setText("Build Started...");

            }

            public void gvtBuildCompleted(GVTTreeBuilderEvent e) {

                label.setText("Build Done.");

                frame.pack();

            }

        });

 

        svgCanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter() {

            public void gvtRenderingPrepare(GVTTreeRendererEvent e) {

                label.setText("Rendering Started...");

            }

            public void gvtRenderingCompleted(GVTTreeRendererEvent e) {

                label.setText("");

            }

        });

 

        return panel;

    }

}


3: 运行中的 SVG 应用程序

事件处理机制

如上例所示,每当设置 JSVGCanvas URI SVG DOM 时(通过 setURI setSVGDocument 方法),相关文档首先被解析(在 URI 的情况),然后创建、渲染和有选择的更新。为了接收这些不同的阶段的事件通知,正确的方法是实现一个侦听器并附加到该组件。有五种类型的侦听器:

  • SVGDocumentLoaderListener 提供了用于跟踪 SVGDocumentLoaderEvent 事件的一组方法。它描述了SVG装载阶段,即使用 SVG 文件创建 SVG DOM 树。
  • GVTTreeBuilderListener 提供了用于跟踪 GVTTreeBuilderEvent 事件的一组方法。它描述了创建阶段,即通过 SVG DOM 树创建一个 GVT (图形矢量工具集),然后 GVT 被用于渲染文档。
  • SVGLoadEventDispatcherListener 提供了用于跟踪 SVGLoadEventDispatcherEvent 事件的一组方法。它描述了 DOM 'SVGLoad' 的事件派发阶段。该事件仅在动态类型文档中触发。
  • GVTTreeRendererListener 提供了用于跟踪 GVTTreeRendererEvent 事件的一组方法。它描述了渲染阶段,即使用一个 GVT 树创建图像。在动态文档中该事件只在最初渲染时被触发一次。
  • UpdateManagerListener 提供了用于跟踪 UpdateManagerEvent 事件的一组方法。它描述了运行阶段,即显示 更新管理器启动,然后显示线程可能被挂起、恢复或停止。该侦听器可用于跟踪图像更新情况。只有动态文档触发该事件。

使用 JavaTM 脚本

Batik 工具集提供了简便的,基于 JavaTM 语言的 SVG 文档脚本。在前一节中,我们学习了如何显示一个 SVG 文档;本节描述如何操作当前在 JSVGCanvas 中显示的 SVG 文档。下面的例子中演示了如何操作 SVG 文档。注意开发人员不需要考虑图像的更新问题,在事件侦听器激活后画布根据需要进行自动更新。

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.JFrame;

import org.apache.batik.swing.JSVGCanvas;

import org.apache.batik.swing.svg.SVGLoadEventDispatcherAdapter;

import org.apache.batik.swing.svg.SVGLoadEventDispatcherEvent;

import org.apache.batik.script.Window;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.events.Event;

import org.w3c.dom.events.EventListener;

import org.w3c.dom.events.EventTarget;

 

public class SVGApplication {

    public static void main(String[] args) {

        new SVGApplication();

    }

 

    JFrame frame;

    JSVGCanvas canvas;

    Document document;

    Window window;

 

    public SVGApplication() {

        frame = new JFrame();

        canvas = new JSVGCanvas();

        // Forces the canvas to always be dynamic even if the current

        // document does not contain scripting or animation.

        canvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);

        canvas.addSVGLoadEventDispatcherListener

            (new SVGLoadEventDispatcherAdapter() {

                    public void svgLoadEventDispatchStarted

                        (SVGLoadEventDispatcherEvent e) {

                        // At this time the document is available...

                         document = canvas.getSVGDocument();

                        // ...and the window object too.

                        window = canvas.getUpdateManager().

                            getScriptingEnvironment().createWindow();

                         // Registers the listeners on the document

                        // just before the SVGLoad event is dispatched.

                        registerListeners();

                        // It is time to pack the frame.

                        frame.pack();

                    }

                });

        frame.addWindowListener(new WindowAdapter() {

                public void windowOpened(WindowEvent e) {

                    // The canvas is ready to load the base document

                    // now, from the AWT thread.

                    canvas.setURI("doc.svg");

                }

            });

        frame.getContentPane().add(canvas);

        frame.setSize(800, 600);

        frame.show();

    }

 

    public void registerListeners() {

        // Gets an element from the loaded document.

        Element elt = document.getElementById("elt-id");

        EventTarget t = (EventTarget)elt;

        // Adds a 'onload' listener

        t.addEventListener("SVGLoad", new OnLoadAction(), false);

        // Adds a 'onclick' listener

        t.addEventListener("click", new OnClickAction(), false);

    }

 

    public class OnLoadAction implements EventListener {

        public void handleEvent(Event evt) {

            // Make some actions here...

            // ... for example start an animation loop:

            window.setInterval(new Animation(), 50);

        }

    }

 

    public class OnClickAction implements EventListener {

        public void handleEvent(Event evt) {

            // Make some actions here...

             // ... for example schedule an action for later:

            window.setTimeout(new DelayedTask(), 500);

        }

    }

 

    public class Animation implements Runnable {

        public void run() {

            // Insert animation code here...

        }

    }

 

    public class DelayedTask implements Runnable {

        public void run() {

            // Make some actions here...

            // ... for example displays an alert dialog:

            window.alert("Delayed Action invoked!");

        }

    }

}

SVG 文档中注册的 DOM 侦听器在画布更新线程中被激活。为了避免冲突的情况,开发人员不应该在另一个线程中操作 DOM 树,而应当切换到画布更新线程进行更新操作。从外部线程切换到画布更新线程的方法如下:

// Returns immediately

canvas.getUpdateManager().getUpdateRunnableQueue().

    invokeLater(new Runnable() {

       // Insert some actions on the DOM here

    });

// Waits until the Runnable is invoked

canvas.getUpdateManager().getUpdateRunnableQueue().

    invokeAndWait(new Runnable() {

       // Insert some actions on the DOM here

    });

与常规的事件侦听器相似,当 Runnable 从更新线程激活时,图形被更新。

Batik 同时提供了 SVG<script> 元素的扩展,以便在 SVG 文档中执行 Java 程序。所有使用 bridge 模块的 Batik 应用程序都可以使用该功能(例如 JSVGCanvas ImageTranscoder 模块)。为了使用该扩展, <script> 元素中的 'type' 属性必须设置为 application/java-archive 。另外, xlink:href 属性应设置为执行程序所在的 jar 文档 URI 地址。该 jar 文件的表述文件( manifest )必须包括下表中的入口项:

Script-Handler: <classname>

<classname> 必须是实现 org.apache.batik.script.ScriptHandler 接口的类的名称。该类可以直接放在 jar 文件中,也可以位于表述文件 Class-Path 入口项所包含的其它 jar 文件中。

总结

在本文中,我们了解到开发人员如何使用 Batik 工具集创建、操作和显示 SVG 内容。 Batik 的模块具有良好的扩展性而且易于使用,通过本文的学习, JavaTM 开发人员现在可以着手编写客户端或服务器端的 SVG 应用程序。另外, Batik 项目是 Apache 软件基金会 (ASF) 倡导的开源志愿项目。这就意味着有很多方式对该项目贡献自己的力量,包括直接参与(编码、写文档、回答问题、提供想法、报告错误、错误修改建议等等),或资源捐献(公开代码、硬件、软件、出席会议、演讲等)。本项目特别关注使用 Batik 模块的应用程序,包括各种工具和扩展,因此请积极的通过 Batik 邮件列表为本项目作出贡献,邮件列表为 batik-users@xml.apache.org

参考资料

[1] "The official SVG page at W3C"

SVG 工作组,网址 http://www.w3.org/Graphics/svg .

[2] "The Document Object Model"

DOM 工作组,网址 http://www.w3.org/DOM .

[3] "The Batik SVG Generator Tutorial"

Batik 小组,网址 http://xml.apache.org/batik/svggen.html .

http://www.svgopen.org/2002/papers/kormann__developing_svg_apps_with_batik/

 

分享到:
评论

相关推荐

    Eclipse 的svg插件batik-plugin

    Batik是为想使用svg格式图片来实现各种功能的应用程序和Applet提供的一个基于java的工具包。 工程创建的目的是为开发者提供一系列可以结合或单独使用来支持特殊的svg解决方案的核心模块。模块主要有SVGParser,...

    Batik详细教程

    Batik 是为想使用 svg 格式图片来实现各种功能的应用程序和 Applet 提供的一个基于 java 的工具包。 工程创建的目的是为开发者提供一系列可以结合或单独使用来支持特殊的 svg 解决方案的核心模块。模块主要有 ...

    基于Batik的java客户端程序

    2. **解析SVG**:使用`SVGGeneratorContext`和`SVGGraphics2D`来解析SVG文件,创建SVG图形对象。 3. **绘制SVG**:将SVG对象与Java的图形组件(如Swing的`JComponent`或JavaFX的`Node`)关联,通过重写`...

    svg_jar Batik

    Batik的目标是使SVG成为Java应用程序和小程序中的主流图形格式,用于查看、操纵或生成SVG内容。它包含了一系列的模块,支持SVG的解析、渲染、转换以及生成。 **SVG解析** 在Batik中,是通过`SVGParser`实现的。这个...

    Batik 1.7 API CHM格式

    Batik是使用svg格式图片来实现各种功能的应用程序以及Applet提供的一个基于java的工具包。 通过Batik,你可以在JAVA可以使用的地方操作SVG文档,您还可以在你的应用程序使用Batik模块来生成 , 处理和转码SVG图像。...

    org.apache.batik包

    在Java 1.4及更高版本中使用Batik,开发者可以轻松地集成SVG功能到他们的应用程序中,创建交互式图形界面,或者生成高质量的图形输出。由于SVG是基于XML的,因此可以利用XML工具和库进行处理,这增加了其灵活性和可...

    batik-1.13.rar

    Batik是Apache软件基金会开发的一个开源项目,主要目标是...此外,由于SVG是开放标准,因此使用Batik开发的应用程序具有跨平台兼容性和长期的可维护性。对于需要处理SVG图像的Java项目, Batik是一个不可或缺的工具。

    batik框架 jar包

    这使得开发者可以在Java应用程序中嵌入SVG图像,或者通过Web服务动态生成SVG图像。 3. **SVG到其他格式转换**: Batik框架提供了一种将SVG图像转换为其他格式的能力,如将SVG转换为常见的位图格式(如PNG、JPEG),...

    batik源码(包含sample)

    4. **SVG生成器**: Batik也提供了生成SVG文档的功能,允许程序动态创建SVG图形,这对于动态数据可视化和Web应用尤其有用。 5. **Rasterizer工具**: Batik的Rasterizer工具能够将SVG文件批量转换为位图图像,这在...

    史上最全的SVG例子

    使用Batik开发SVG应用程序_阿生空间.mht`、`Batik(四)---3-涛涛 - 新浪BLOG.mht`:这些MHT文件是关于SVG和Batik技术的文章或教程, Batik是Apache软件基金会的一个项目,提供了一套处理SVG的工具集,包括将SVG转换为...

    使用Java创建图形绘制应用程序 - 一个实战教程

    在本教程中,我们将学习如何使用Java编程语言和Java Swing库创建一个图形绘制应用程序。这个应用程序将提供用户绘制、编辑和保存图形的功能,涵盖以下核心知识点: 1. **Java Swing库**:Java Swing是Java GUI...

    SVG转EMF的示例代码

    2. 使用Batik的SVGGeneratorContext和SVGGraphics2D创建一个SVG到EMF的转换上下文。 3. 将SVG图形渲染到SVGGraphics2D对象中。 4. 使用转换上下文将SVGGraphics2D对象写入EMF输出流,通常是FileOutputStream。 5. ...

    batik-1.5-fop-0.20-5.zip batik-1.5-fop-0.20-5.jar

    `META-INF`目录在Java应用程序中是标准的,它存储元数据信息,例如项目的MANIFEST.MF文件,这个文件包含了关于JAR文件的元信息,如版本、作者、依赖库等。在FOP的上下文中,MANIFEST.MF可能会指定FOP的主类或者其他...

    batik的相关jar包

    它们是处理XML相关的Java应用程序的必备组件。 在开发中,这些jar包通常需要一起添加到项目的类路径中,以便充分利用Batik和其他相关工具的功能。例如,如果你需要从SVG生成PDF,你可能需要使用FOP、pdf-transcoder...

    batik .jar 与设计模式

    2. 工厂模式:用于创建SVG图形对象。通过工厂类,可以灵活地生成各种类型的图表,如折线图、柱状图或饼图,而无需暴露具体的实现细节。 3. 单例模式:在需要全局唯一的SVG渲染引擎或解析器时,单例模式可以确保在...

    基于JavaScript及JAVA的SVG交互应用.pdf

    【DOM事件】是DOM规范的一部分,它允许开发者编写SVG交互应用程序。当用户与SVG图形交互(如点击、鼠标移动等)时,会触发DOM事件,进而调用相应的JavaScript函数来处理这些交互。 【JavaScript与SVG交互】...

    svg_jars.7z

    这些jar文件组合在一起,可以让你在Java应用程序中轻松地实现SVG的读取、解析、绘制、编辑和动画等操作。例如,你可以用它们来将SVG图标动态加载到用户界面,或者将SVG图像转换为其他格式,如位图。在实际开发中,...

    基于SVG的SCADA监控画面生成软件的设计与开发

    IEC 61970是一个国际标准,它规定了能量管理系统应用程序接口的公共信息模型(CIM)以及基于XML的数据交换格式。IEC 61970标准的推出促使SCADA系统朝向标准化、规范化发展。在SCADA系统中,图形系统软件作为人机交互...

    svg-android,安卓SVG矢量图形支持.zip

    SVG(Scalable Vector Graphics)是一种基于XML的矢量图像格式,它允许在网页和应用程序中创建和显示复杂的图形,而这些图形无论放大多少倍都能保持清晰无损。在Android平台上,由于原生系统对SVG的支持有限,开发者...

    svg.rar_SVG java_svg_手机 视频_手机游戏处理_手机视频

    通过Batik,开发者可以在Java应用程序中创建、编辑和显示SVG图像,这在手机游戏的图形界面设计和动态图形生成中非常有用。 在手机视频开发中,SVG可以用于创建复杂的动画效果和图形过渡,提高视频的视觉吸引力。...

Global site tag (gtag.js) - Google Analytics