I'm trying to modify the SVG document in runtime and go repainting the modifications performed to the SVG:
I need your help, i'm trying with repaint method, but is not posible refresh the SVG Canvas.
this is the code:
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.*;
import java.io.StringReader;
import javax.swing.*;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.swing.*;
import org.apache.batik.svggen.*;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
public class BatikViewGeneratedSVGDemo extends JFrame implements MouseListener, MouseMotionListener{
String xmlSVG;
SVGDocument svgDoc;
Element svgRoot;
JSVGCanvas canvas;
public BatikViewGeneratedSVGDemo() throws HeadlessException {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(600, 600));
setMinimumSize(new Dimension(600, 600));
String xmlSVG = ""
+ "<?xml version=\"1.0\" standalone=\"no\"?>\n" +
"<svg "
+ "contentScriptType=\"text/ecmascript\" "
+ "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
+ "xmlns=\"http://www.w3.org/2000/svg\"\n"
+ "baseProfile=\"full\"\n "
+ "zoomAndPan=\"magnify\" "
+ "contentStyleType=\"text/css\" "
+ "preserveAspectRatio=\"xMidYMid meet\" "
+ "width=\"600\" "
+ "height=\"600.0px\" "
+ "viewBox='0 0 716.3783 753.51105'"
+ " version=\"1.0\" >\n "
+ " <ellipse id='circulo1' fill-opacity=\"0.5\" fill=\"#ff0033\" rx=\"58.0\" cx=\"238.0\" ry=\"45.5\" cy=\"180.5\" stroke=\"#000000\"/>\n "
+ "</svg>";
StringReader reader = new StringReader(xmlSVG);
String uri = "nothing";
try {
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
svgDoc = f.createSVGDocument(uri, reader);
Element circulo = svgDoc.getElementById("circulo1");
System.out.println("opacidad: " + circulo.getAttribute("fill-opacity"));
svgRoot = svgDoc.getDocumentElement();
// Display the document.
canvas = new JSVGCanvas();
System.out.println("doc.width: " + svgRoot.getAttribute("width"));
getContentPane().add(canvas, BorderLayout.CENTER);
canvas.setSVGDocument(svgDoc);
JButton btn = new JButton("Crear Circulo");
btn.addMouseListener(this);
getContentPane().add(btn, BorderLayout.SOUTH);
System.out.println("ancho: " + canvas.getSize().width + " alto: " + canvas.getSize().height);
} catch (Exception ex) {
System.out.println("ocurriĆ³ un error");
} finally {
reader.close();
}
}
@Override
public void mouseClicked(MouseEvent e) {
crearCirculo();
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseDragged(MouseEvent e) {}
@Override
public void mouseMoved(MouseEvent e) {}
public void crearCirculo() {
Element newCircle = svgDoc.createElement("ellipse");
newCircle.setAttribute("id", "circulo2");
newCircle.setAttribute("fill-opacity", "0.5");
newCircle.setAttribute("fill", "#990055");
newCircle.setAttribute("rx", "100");
newCircle.setAttribute("cx", "150");
newCircle.setAttribute("ry", "100");
newCircle.setAttribute("cy", "150");
newCircle.setAttribute("stroke", "#990055");
System.out.println("XML: "+svgDoc.getRootElement().getXMLbase());
svgRoot.appendChild(newCircle);
canvas.setSVGDocument(svgDoc);
System.out.println("opacidad2: " + svgDoc.getElementById("circulo2").getAttribute("fill-opacity"));
System.out.println("entra");
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
BatikViewGeneratedSVGDemo obj = new BatikViewGeneratedSVGDemo();
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
obj.setVisible(true);
}
});
}
}
You should create a Runnable with all modifications to the SVG document and then use JSVGCanvas Update Manager's Runnable Queue to call this Runnable and all changes to take effect.
public Runnable r = new Runnable() {
@Override
public void run() {
value = value + 10;
svgCanvas.evaluate("setlevel(" + value + ",'Text')");
}
};
And then,
svgCanvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(r);
Everything done outside this queue will not take effect inmediatly.