Title: Scripting With Java

#Scripting With Java


This page explains how to manipulate the DOM tree of an SVG document from a Java program.

## How to manipulate a document in a JSVGCanvas { #Swing}

The follow code template demonstrates how to manipulate an SVG document displayed in a [JSVGCanvas](../../javadoc/org/apache/batik/swing/JSVGCanvas.html) directly from a Java program.
You don’t have to worry about graphics updates; after each event listener invocation the canvas is updated if needed.

    :::java
    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) {
                // Perform some actions here...

                // ...for example start an animation loop:
                window.setInterval(new Animation(), 50);
            }
        }

        public class OnClickAction implements EventListener {
            public void handleEvent(Event evt) {
                // Perform 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() {
                // Perform some actions here...

                // ...for example displays an alert dialog:
                window.alert("Delayed Action invoked!");
            }
        }
    }

## Writing thread-safe code { #Threads}

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:

    :::java
    // Returns immediately
    canvas.getUpdateManager().getUpdateRunnableQueue().
        invokeLater(new Runnable() {
            public void run() {
                // Insert some actions on the DOM here
            }
        });
    or:
    // Waits until the Runnable is invoked
    canvas.getUpdateManager().getUpdateRunnableQueue().
        invokeAndWait(new Runnable() {
            public void run() {
                // Insert some actions on the DOM here
            }
        });

Like with event listeners, when a [Runnable](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runnable.html) is invoked from the update thread, the graphics are updated.
It is very dangerous to call `invokeAndWait` from the Swing event thread. This is the only thread that can be used to interact with Swing components. In some cases DOM calls may need to query the canvas for information (such as actual Swing component size, etc). If this happens you will get a thread deadlock. You should only make invokeAndWait calls from “third party” threads.

# Using the SVG DOM { #SVGDOM}

Batik provides a fairly complete implementation of the SVG DOM. The SVG DOM provides all the functionality most applications require. In particular, the DOM implements DOM Events, including mutation and UI Events. As an example, DOM events allow you to get notified when the cursor moves over elements of interest:

    :::java
    // Element of Interest.
    Element theElem = ...;
    ((EventTarget) theElem).addEventListener("mouseover", mouseOverListener, true);

where `mouseOverListener` implements the [org.w3c.dom.events.EventListener](http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/events/EventListener.html) interface. This interface consists of the method:

    :::java
    void handleEvent(Event evt);

This is called whenever the event occurs with the element it is registered on. It is worth reviewing the DOM Events specification as there are many useful features to this interface that are not immediately obvious.

It is also worth looking at the DOM interfaces defined by the SVG specification as they provide a large number of useful methods, in particular those of [SVGLocatable](../../javadoc/org/w3c/dom/svg/SVGLocatable.html):

    :::java
    // Returns Bounding box of SVG Element.
    public SVGRect   getBBox();
    // Returns the transformation matrix to the screen.
    public SVGMatrix getScreenCTM();
    // Returns the transformation matrix to the given element.
    public SVGMatrix getTransformToElement(SVGElement element)
                    throws SVGException;

In particular, `getScreenCTM` is very useful for taking the `clientX` and `clientY` attributes of the DOM [UIEvent](http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/events/UIEvent.html) and mapping them to the coordinate system of an element in the SVG document:

    :::java
    SVGMatrix mat  = elem.getScreenCTM();
    SVGMatrix imat = mat.inverse();
    SVGPoint  cPt  = document.getRootElement().createSVGPoint();
    cPt.setX(uiEvt.getClientX());
    cPt.setY(uiEvt.getClientY());
    cPt = cPt.matrixTransform(imat);

# Referencing Java code from a document { #javaInDocument}

Batik implements the Java bindings for SVG, and thus allows Java code to be referenced from `script` elements. 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 that contains the code to run.

The manifest of this jar file must contains an entry of the form:

    SVG-Handler-Class: classname

where *classname* must be the name of a class that implements the [org.w3c.dom.svg.EventListenerInitializer](../../javadoc/org/w3c/dom/svg/EventListenerInitializer.html) interface. Just before the document `SVGLoad` event is fired, an instance of this class is created, and this instance has its `initializeEventListeners` method invoked. Note that there is no way to specify Java handlers in event attributes on SVG elements, so having the `initializeEventListeners` call `addEventListener` on a node is the only way to attach a Java listener from within the document.

The class specified by `SVG-Handler-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.
