Can I create a JSVGCanvas without an svg file?

801 views Asked by At

Looking through the documentation for JSVGCanvas, it seems like I might not be able to do this. However, it makes a lot of sense for this to be possible. How can I create a JSVGCanvas from a String variable instead of a File?

My idea is that I could do something like the following:

String svg = "svg data";
JFrame frame = new JFrame();
JSVGCanvas canvas = new JSVGCanvas();
canvas.setContentsFromString(svg);
frame.add(canvas);
frame.setVisible(true);

I know I could always create a temporary file and set the contents of the JSVGCanvas from the file, but I'd rather avoid that. Could I perhaps extend File and override its methods?

Note: I am using Jython, but I think that this is relevant for Java as well, hence I'm using both tags. I'd prefer that a solution be in Java, but a Jython solution would work

1

There are 1 answers

4
Justin On BEST ANSWER

Yes, you can:

String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
SVGDocument document = factory.createSVGDocument("", new ByteArrayInputStream(svg.getBytes("UTF-8")));

canvas.setSVGDocument(document);

This works by creating an SVGDocument via SAXSVGDocumentFactory. SAXSVGDocumentFactory has a method createSVGDocument(String, InputStream), where the string is supposed to be a URI to the file that the InputStream represents. However, we abuse that and give it an empty string, and make the InputStream a stream from our svg-data String.

Using "" might throw an exception about their being no protocol, depending on the version of Batik. If that's the case, try "file:///", that is, give it a URI that is a lie. You may want to use an actual URI; you'd need to figure out a valid one to give to Batik