<?xml version="1.0"?>

<!--

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

-->

<!-- ========================================================================= -->
<!-- author shillion@ilog.fr                                                   -->
<!-- version $Id: javaScripting.xml 201374 2004-08-18 07:17:26Z vhardy $ -->      
<!-- ========================================================================= -->

<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
  <header>
    <title>Scripting With Java</title>
  </header>

  <body>
    <p>
      This page explains how to manipulate the DOM tree of an SVG
      document from a Java program.
    </p>

    <section id="Swing">
      <title>How to manipulate a document in a JSVGCanvas</title>
      <p>
        The follow code template demonstrates how to manipulate an SVG
        document displayed in a
        <a class="class" href="../../javadoc/org/apache/batik/swing/JSVGCanvas.html">JSVGCanvas</a>
        directly from a Java program.
      </p>
      <note>
        You don’t have to worry about graphics updates; after each event
        listener invocation the canvas is updated if needed.
      </note>
      <source>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!");
        }
    }
}
</source>
      </section>
  
    <section id="Threads">
      <title>Writing thread-safe code</title>
      <p>
        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.
      </p>
      <p>
        The way to switch from an external thread to the canvas update
        thread is to use the following code:
      </p>
      <source>// Returns immediately
canvas.getUpdateManager().getUpdateRunnableQueue().
    invokeLater(new Runnable() {
        public void run() {
            // Insert some actions on the DOM here
        }
    });</source>
      <p>or:</p>
      <source>// Waits until the Runnable is invoked
canvas.getUpdateManager().getUpdateRunnableQueue().
    invokeAndWait(new Runnable() {
        public void run() {
            // Insert some actions on the DOM here
        }
    });</source>
      <p>
        Like with event listeners, when a
        <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runnable.html">Runnable</a>
        is invoked from the update thread, the graphics are updated.
      </p>
      <note>
        It is very dangerous to call <code>invokeAndWait</code> 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.
      </note>
    </section>

    <section id="SVGDOM">
      <title>Using the SVG DOM</title>
      <p>
        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:
      </p>
      <source>// Element of Interest.
Element theElem = ...;
((EventTarget) theElem).addEventListener("mouseover", mouseOverListener, true);</source>
      <p>
        where <code>mouseOverListener</code> implements the
        <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/events/EventListener.html">org.w3c.dom.events.EventListener</a>
        interface.  This interface consists of the method:
      </p>
      <source>void handleEvent(Event evt);</source>
      <p>
        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.
      </p>
      <p>
        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
        <a class="class" href="../../javadoc/org/w3c/dom/svg/SVGLocatable.html">SVGLocatable</a>:
      </p>
<source>// 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;</source>
      <p>
        In particular, <code>getScreenCTM</code> is very useful for
        taking the <code>clientX</code> and <code>clientY</code> attributes of
        the DOM
        <a class="class" href="http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/events/UIEvent.html">UIEvent</a>
        and mapping them to the coordinate system of an element in the SVG
        document:
      </p>
      <source>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);</source>
    </section>

    <section id="javaInDocument">
      <title>Referencing Java code from a document</title>
      <p>
        Batik implements the Java bindings for SVG, and thus allows Java
        code to be referenced from <code>script</code> elements.
        This feature is available to any application of Batik that uses
        the bridge module (for example the Swing component and the
        transcoders).
      </p>
      <p>
        In order to use this extension, the <code>type</code> attribute
        of a <code>script</code> element must be set to
        <code>application/java-archive</code>. In addition, the
        <code>xlink:href</code> attribute must be the URI of a jar file
        that contains the code to run.
      </p>
      <p>
        The manifest of this jar file must contains an entry of the form:
      </p>
      <source>SVG-Handler-Class: <em>classname</em></source>
      <p>
        where <em>classname</em> must be the name of a class that
        implements the
        <a class="class" href="../../javadoc/org/w3c/dom/svg/EventListenerInitializer.html">org.w3c.dom.svg.EventListenerInitializer</a>
        interface.  Just before the document <code>SVGLoad</code> event
        is fired, an instance of this class is created, and this instance has
        its <code>initializeEventListeners</code> method invoked.  Note that
        there is no way to specify Java handlers in event attributes on
        SVG elements, so having the <code>initializeEventListeners</code>
        call <code>addEventListener</code> on a node is the only way to
        attach a Java listener from within the document.
      </p>
      <p>
        The class specified by <code>SVG-Handler-Class</code> 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
        <code>Class-Path</code> entry of the manifest.
      </p>
    </section>

  </body>
</document>
