http://xml.apache.org/http://www.apache.org/http://www.w3.org/

Home

Overview
FAQ
License
Download
Install
Demo

In the news

Tools and Apps
Browser
Rasterizer
Font Converter
Pretty-printer

Architecture
API (Javadoc)
Generator
DOM API
JSVGCanvas
Transcoder API

Scripting Intro
Scripting Features
Java Scripting
Security

Extensions

Testing

Contributors
Mail Lists

CVS Repository
Bug Database

Status

Glossary


Introduction

This section explains how to manipulate the DOM tree of an SVG document from a Java program. It contains the following sub-sections:


How to manipulate a JSVGCanvas DOM document

The follow code template demonstrates how to manipulate an SVG document displayed in a JSVGCanvas directly from a Java program.

NoteYou don't have to worry about graphics updates: after each event listener invocation the canvas is updated if needed.

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!");
        }
    }
}

Writing thread-safe code

The DOM listeners registered on the SVG document are called from the canvas update thread. To avoid race conditions do not manipulate the DOM tree from another thread.
The way to switch from an external thread to the canvas update thread is to use the following code:

// Returns immediately
canvas.getUpdateManager().getUpdateRunnableQueue().
    invokeLater(new Runnable() {
       // Insert some actions on the DOM here
    });

- or -

// Waits until the Runnable is invoked
canvas.getUpdateManager().getUpdateRunnableQueue().
    invokeAndWait(new Runnable() {
       // Insert some actions on the DOM here
    });

Like with event listeners, when a Runnable is invoked from the update thread, the graphics are updated.


Alternate way to manipulate an SVG document

Batik provides an extension of the SVG <script> element which allows Java programs to be called from an SVG document. This feature is available to any application of Batik that uses the bridge module (for example the Swing component and the transcoders).

In order to use this extension, the type attribute of a <script> element must be set to application/java-archive. In addition the xlink:href attribute must be the URI of a jar file which contains the program to run. The manifest of this jar file must contains an entry of the form:

Script-Handler: classname

Where classname must be the name of a class which implements the org.apache.batik.script.ScriptHandler interface. See the javadoc of this interface for more details.
The class can be contained directly in the jar file, but it is also possible for it to be contained in a jar file added to the classpath using the Class-Path entry of the manifest.



Copyright © 2000-2002 The Apache Software Foundation. All Rights Reserved.