xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <Roland.Webe...@t-systems.com>
Subject AW: Batik and XmlHttpRequest / accessing Batik objects from javascript in svg
Date Thu, 07 Oct 2010 12:57:30 GMT
Hi there,

I hust tried to bind my applet to the script interpreter. Unfortunetaly, this does not work
as expectet. I found the bridgeContext of the JSVGCanvas to be protected. Thus I derived a
simple class from JSVGCanvas like this:

public class MySVGCanvas extends JSVGCanvas {

      public void bindObjectToInterpreter(String language, String name, Object obj){
            System.out.println("### Binding Object " + obj.toString() + " to interpreter.");
            Interpreter interpreter = this.bridgeContext.getInterpreter(language);
            interpreter.bindObject(name, obj);
      }
}

The difficulty is WHEN to bind the object. First try was to simply call it in the init()-Method
of the Applet after using canvas.setURI(...). However, this method is async, so my bind-method
will not yet find even a bridgeContext (it is null). Therefore, I thought it would be best
to bind the object AFTER the document is loaded (via setURI) by using something like:

            canvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter() {
                public void documentLoadingStarted(SVGDocumentLoaderEvent e) {

                }
                public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
                  System.out.println("### Document loaded");
                  canvas.bindObjectToInterpreter("text/ecmascript", "parentapplet", canvas);
                }
            });

Currently, this should bind the canvas (later it should be the applet) to the name "parentapplet"
in the interpreter and I should be able to use this name as a global variable in my ecmascript,
e.g. like alert(parentapplet); Correct?  However, an exception is thrown when binding the
object:

### Document loaded
### Binding Object test.MySVGCanvas[,0,36,1000x964,alignmentX=0.0,alignmentY=0.0,border=,flags=288,maximumSize=,minimumSize=java.awt.Dimension[width=100,height=100],preferredSize=java.awt.Dimension[width=200,height=200]]
to interpreter.
java.lang.RuntimeException: Unknown document
            at org.apache.batik.bridge.BridgeContext.getInterpreter(BridgeContext.java:558)
            at test.MySVGCanvas.bindObjectToInterpreter(MySVGCanvas.java:15)
            at test.IntercomApplet$5.documentLoadingCompleted(IntercomApplet.java:109)
            at org.apache.batik.swing.svg.SVGDocumentLoader$2.dispatch(SVGDocumentLoader.java:145)
            at org.apache.batik.util.EventDispatcher.dispatchEvent(EventDispatcher.java:103)
            at org.apache.batik.util.EventDispatcher.fireEvent(EventDispatcher.java:87)
            at org.apache.batik.util.EventDispatcher$1.run(EventDispatcher.java:46)
            at java.awt.event.InvocationEvent.dispatch(Unknown Source)
            at java.awt.EventQueue.dispatchEvent(Unknown Source)
            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.run(Unknown Source)
This is because the "document" filed in the interpreter is null. But why? The scripting and
the svg run fine, so it should have a document set, shouldn't it? I'll next check if this
is caused by canvas.setURI(..) - does this not cause the document-field in the interpreter
to be set?

Any suggestions what I'm doing wrong here? I must admit that my knowledge about Batik itself
is still very poor - I mainly adjusted SVGs and ecmascript to be runnable inside Batik until
now and simply use JSVGCanvas inside an applet as a viewer on the webpage. All logic is inside
the SVGs and ecmascript.

Many thanks again,
Roland

________________________________
Von: thomas.deweese@kodak.com [mailto:thomas.deweese@kodak.com]
Gesendet: Mittwoch, 29. September 2010 12:28
An: batik-users@xmlgraphics.apache.org
Cc: batik-users@xmlgraphics.apache.org
Betreff: Re: Batik and XmlHttpRequest / accessing Batik objects from javascript in svg

Hi Roland,

<Roland.Weber01@t-systems.com> wrote on 09/17/2010 08:45:30 AM:

> However, I got 2 main problems in getting my existing SVGs run in an
> Applet with JSVGCanvas:
>
> 1) The Adobe Plugin is currently embedded into an HTML page via the
> embed-tag. This enables all scripts in the SVGs to access all Html-
> Elements/Javascripts  from the OUTER HTML page and vice versa. That
> means I can define a Javascript object in a script block on the HTML
> and use it inside the Javascript of the SVG out of the box. Or for
> example I can get hold of a DIV-Element from the outer HTML page by
> calling something like
>
> parent.document.getElementById(<divId>);
>
> from within javscript inside SVG.
>
> No discussion on whether this is a good design or concept - fact is,
> that the Javascript in the existing SVGs heavily relies on
> Javascript blocks and Elements of the surrounding HTML page. My
> question is: Is there a way to achieve the same effect when using an
> Applet with JSVGCanvas to display the SVGs? Probably not.

        Correct, I don't believe this is possible.  It's only possible in
Adobe because they can actually run their scripts in the Browsers script
engine such an option is not AFAIK available for Java.

> However, I could surpass this by calling a method from my Applet
> from inside the SVG's Javascript (as I can get hold of Elements of
> the HTML page from my Applet). The question is: How to access The
> JSVGCanvas or the Applet object from javascript within SVG? Is there
> a way, maybe via the Rhino engine?

        You will need to a little bit of setup in Java first.  Basically
you need to bind the Applet and or JSVGCanvas object to a global in
the JavaScript interpreter.  You can do this by calling
'getInterpreter(String lang)' (lang should probably be "text/ecmascript")
on the BridgeContext associated with the JSVGCanvas.  This will give
you the Interpreter that is being used.  On that object you can call
'bindObject(String name, Object obj)'.

        That will bind 'obj' to 'name' as a global in the script environment.
>From their Rhino does a decent job of exposing Java methods into JavaScript.

> 2) A related problem is the current communication. Within the Adobe
> plugin, I can access the browsers XmlHttpRequest object and use it
> for ajax-like communication from within the SVG. This doesn't work
> within the Applet with JSVGCanvas. Isn't there something like a
> lightweight XmlHttpRequest object available in Batik?

        Check 'getURL', and parseXML, they are generally a decent work
alike (not quite as flexible).

> If not, would it be possible to call some Java code from within the SVGs
> Javascript to build some similar communication and how does this
> work? Would security settings deny this (can't use signed Applets)
> if I only would connect to the same server/codedbase? Ajax-like
> communication within the svg is awesome, it makes the graph/
> workfloweditor quite fast with the Adobe Plugin - this would be a
> point Batik could really benefit from when it comes to developer and
> customer acceptance!

        As I said above you can expose your own Java methods fairly
easily.  You are bound by the Applet sandbox (as it Batik) so you
are restricted in the servers you can connect to (of course you
should have similar restrictions with XmlHttpRequest).

Good luck.

Mime
View raw message