|
(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 */ 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> |
- TEXT selection dilemma - getCharNumAtPosition Baron, Randy {PRG~Basel}
- RE: TEXT selection dilemma - getCharNumAtPos... Thierry Kormann
- Baron, Randy {PRG~Basel}
