如何在编辑SVGDocument后重新绘制JSVGCanvas?使用Apache Batik

时间:2014-07-23 04:02:14

标签: java xml apache svg batik

我正在尝试在运行时修改SVG文档并重新绘制对SVG执行的修改:

我需要你的帮助,我正在尝试使用重绘方法,但是不能刷新SVG画布。

这是代码:

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

1 个答案:

答案 0 :(得分:0)

您应该创建一个对SVG文档进行所有修改的Runnable,然后使用JSVGCanvas Update Manager的Runnable Queue来调用此Runnable并使所有更改生效。

public Runnable r = new Runnable() {

        @Override
        public void run() {
            value = value + 10;
            svgCanvas.evaluate("setlevel(" + value + ",'Text')");
        }
    };

然后,

svgCanvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(r);

在此队列之外完成的所有操作都不会立即生效。