(not sure if this message got through the first time...)

 

Hi,

   I hope this could be a trivial problem for someone on the list, because it’s not for me.

   I am trying to use SVGTextElement methods getStartPositionOfChar and getCharNumAtPosition to find out which character in a string was clicked on (code below).  The only thing I get though is a runtime error:

 

java.lang.RuntimeException:  !!! SVGOMTextContentElement.getStartPositionOfChar()

        at org.apache.batik.dom.svg.SVGOMTextContentElement.getStartPositionOfChar(Unknown Source)

        at svgstuff.SVGTextSelectTest$OnMouseClick.handleEvent(SVGTextSelectTest.java:155)

        at org.apache.batik.dom.events.EventSupport.fireEventListeners(Unknown Source)

            etc...

.

  I’m using JDK 1.4 and batik-1.5beta4b on Windows XP Professional.

  Finding the position could probably also be done with various calculations of font size, mouse position, user coordinate system and so forth, but I thought that if batik provided a method for it, it would be easier (maybe not though).

   Any pointers in the right direction would be appreciated

 

sincerely,

Randy Baron

 

 

 

 

*************** SVGMouseTracker.java source code:

 

 

package svgstuff;

 

/*

 * SVGMouseTracker.java

 *

 * Created on October 10, 2002, 1:57 PM

 */

import java.io.*;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import org.apache.batik.script.Window;

import javax.swing.JFrame;

import javax.swing.JFileChooser;

import org.apache.batik.swing.JSVGCanvas;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.apache.batik.swing.svg.SVGLoadEventDispatcherAdapter;

import org.apache.batik.swing.svg.SVGLoadEventDispatcherEvent;

import org.w3c.dom.events.Event;

import org.w3c.dom.events.EventListener;

import org.w3c.dom.events.EventTarget;

import org.w3c.dom.events.MouseEvent;

import org.w3c.dom.svg.SVGElement;

import org.w3c.dom.NodeList;

import org.apache.batik.dom.svg.SVGOMTextElement;

import org.apache.batik.gvt.event.SelectionListener;

import org.apache.batik.gvt.TextNode;

import org.w3c.dom.svg.SVGPoint;

/**

 *

 * @author  baron

 */

public class SVGTextSelectTest {

   

    JFrame frame;

    JSVGCanvas canvas;

    Document document;

    Window window;

   

    /** Creates a new instance of SVGTextSelectTest */

    public SVGTextSelectTest() {

        // create java frame and batik svg canvas...

        frame = new JFrame();

        canvas = new JSVGCanvas();

       

        // Force 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();

                        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();

                     }

             });

 

 

        /** Pops up file chooser to choose the svg file to display */

        frame.addWindowListener(new WindowAdapter() {

                public void windowOpened(WindowEvent e) {

                    // The canvas is ready to load the base document

                    // now, from the AWT thread.

                    JFileChooser fc = new JFileChooser(".");

                    int choice = fc.showOpenDialog(canvas);

                    if (choice == JFileChooser.APPROVE_OPTION) {

                        File f = fc.getSelectedFile();

                        try {

                            canvas.setURI(f.toURL().toString());

                        } catch (IOException ex) {

                            ex.printStackTrace();

                        }

                    }

                }

        });

 

        /** For closing the window and exiting when the user clicks the close box */

        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent e) {

            System.exit(0);

            }

        });

       

        frame.getContentPane().add(canvas);

        frame.setSize(800, 600);

        frame.show();

        System.out.println("Constructor finished.");         

    }

   

    public static void main (String[] args) {

        System.out.println("Testing test selection methods...");

        SVGTextSelectTest mtrack = new SVGTextSelectTest();

    }

   

    public void registerListeners() {

        // register a listener on the root of the main svg doc

        Element maindoc = (Element)  document.getDocumentElement();

        EventTarget doctarg = (EventTarget) maindoc;

        doctarg.addEventListener("click", new OnMouseClick(), false);

       

    }

 

     public class OnMouseClick implements EventListener {

        public void handleEvent(Event evt) {

            int mx, my;

            int sx, sy;               

            int i = 0;

           

            AnSVGPoint spoint;

 

            // Get mouse click coordinates

            MouseEvent mevt = (MouseEvent) evt;

            mx = mevt.getClientX();

            my = mevt.getClientY();

            sx = mevt.getScreenX();

            sy = mevt.getScreenY();

 

           

            SVGElement targ = (SVGElement) mevt.getTarget();

 

            System.out.println("Mouse X:" + mx + " Y: " + my);

            System.out.println(" in screen coordinates - x: " + sx + " y: " + sy);

            System.out.println("   Type of event: " + mevt.getType());

            System.out.println("   getTarget: " + mevt.getTarget());

            System.out.println("   getCurrentTarget: " + mevt.getCurrentTarget());

            System.out.println("   Element id = " + targ.getId());

           

            if (targ instanceof org.apache.batik.dom.svg.SVGOMTextElement) {

  

                SVGOMTextElement texttarg = (SVGOMTextElement) targ;

                System.out.println("HIT SOME TEXT!");

               

                // This block is not entirely relevant to the getCharNumAtPosition problem; just for info

                // see if there are any subnodes:

                NodeList nlist = targ.getChildNodes();

                System.out.println(" text node length: " +  nlist.getLength());

                while (nlist.item(i) != null) {

                    System.out.println(" text node item " + i + ": " + nlist.item(i++));

                }

               

//ERROR OCCURS HERE ---

                System.out.println(" ...and here comes the error");

 

                // Try to get position of first character in the text string with getStartPositionOfChar (returns an SVGPoint)

                // SVGPoint interface is implemented below

                // Using character zero for example (0 or 1, makes no difference).

 

                spoint = (AnSVGPoint) texttarg.getStartPositionOfChar(0);

                System.out.println("   try getStartPositionOfChar: " + spoint.getX());

 

                // Try to get character under the position where the mouse was clicked.

                spoint.setX((float) mx);

                spoint.setY((float) my);

                System.out.println("   try getCharNumAtPosition: " + texttarg.getCharNumAtPosition(spoint) );

               

            }

        }

    }         

}

   

 

class AnSVGPoint implements SVGPoint {

    float x, y;

   

    public float getX() {

        return this.x;

    }

   

    public float getY() {

        return this.y;

    }

   

    public org.w3c.dom.svg.SVGPoint matrixTransform(org.w3c.dom.svg.SVGMatrix sVGMatrix) {

        // do nothing;

        return this;

    }

   

    public void setX(float param) throws org.w3c.dom.DOMException {

        this.x = param;

    }

   

    public void setY(float param) throws org.w3c.dom.DOMException {

        this.y = param;

    }

   

}

 

 

 

 

 

 

 

 

 

 

   

 

************** Sample SVG file which displays two lines of text:

 

<?xml version="1.0" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg width="400px" height="500px" viewBox="0 0 800 900" xmlns="http://www.w3.org/2000/svg">

 

<g id="sampletext" >

 

            <text id="lineone" font-size="25" x="20" y="40" fill="purple"> ABCDEFGHIJKLMNOPQRSTUVWXYZ</text>

            <text id="linetwo" font-size="25" x="20" y="80"> 1234567890A0987654321</text>

</g>

 

</svg>

 

 

 

Reply via email to