<?xml version="1.0"?>
<!DOCTYPE document SYSTEM "./dtd/document-v10.dtd">

<!--

   Copyright 2002-2004  The Apache Software Foundation 

   Licensed 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$ -->      
<!-- ========================================================================= -->
<document>
  <header>
    <title>Scripting With Java</title>
    <authors>
      <person name="Stephane Hillion" email="shillion@ilog.fr"/>
      <person name="Thomas DeWeese" email="deweese@apache.org"/>
    </authors>
  </header>

  <body>
    <s1 title="Introduction">
    <p>
    This section explains how to manipulate the DOM tree of an SVG
    document from a Java program.  It contains the following
    sub-sections:
    </p>

    <ul>
      <li><link href="#Swing"
            >How to manipulate a JSVGCanvas' document?</link></li>
      <li><link href="#Threads"
            >How to write thread-safe code?</link></li>
      <li><link href="#SVGDOM"
            >Using the SVG DOM</link></li>
      <li><link href="#Extension">
        How to run Java code using a &lt;script&gt; element?</link></li>
    </ul>                          
    </s1>

    <anchor id="Swing"/>
    <s1 title="How to manipulate a JSVGCanvas DOM document">
      <p>
      The follow code template demonstrates how to manipulate an SVG
      document displayed in a JSVGCanvas 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) {
            // 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!");
        }
    }
}
</source>
    </s1>
  
    <!-- #################################################### -->

    <anchor id="Threads"/>
    <s1 title="Writing thread-safe code">
      <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.<br/>
      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
        }
    });

- or -

// 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 Runnable is invoked from the
    update thread, the graphics are updated.
    </p>
    <note>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.
    </note>
    </s1>

    <!-- #################################################### -->

    <anchor id="SVGDOM"/>
    <s1 title="Using the SVG DOM">
      <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.
      </p>
      <p>
        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 <tt>mouseOverListener</tt> implements the
        <tt>org.w3c.dom.events.EventListener</tt> interface.
        This interface consists of the method:
      </p>
<source>
public 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 the SVGLocatable:
      </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 <tt>getScreenCTM</tt> is very useful for
        taking the 'clientX', 'clientY' attributes of the
        DOM UIEvent 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.clientX);
    cPt.setY(uiEvt.clientY);
    cPt = cPt.matrixTransform(imat);
</source>
    </s1>

    <!-- #################################################### -->

    <anchor id="Extension"/>
    <s1 title="Alternate way to manipulate an SVG document">
      <p>
      Batik provides an extension of the SVG
      <code>&lt;script&gt;</code> 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).
      </p>

      <p>

      In order to use this extension, the <code>type</code> attribute
      of a &lt;script&gt; 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
      which contains the program to run.

      The manifest of this jar file must contains an entry of the form:
      <br/><br/>
      <code>SVG-Handler-Class: </code><em>classname</em><br/><br/>

      Where <em>classname</em> must be the name of a class which
      implements the
      <code>org.w3c.dom.svg.EventListenerInitializer</code> interface.
      See the javadoc of this interface for more details.
      <br/>

      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 <code>Class-Path</code> entry of the
      manifest.

      </p>
    </s1>

  </body>
</document>
