如何在Batik中为g元素添加ID属性?

时间:2018-05-27 21:50:16

标签: dom svg batik

我正在使用Batik创建一个SVG文件,我希望稍后在浏览器中打开并使用JavaScript进行操作。我无法弄清楚如何将ID属性添加到创建的g元素。

svgGenerator = new SVGGraphics2D(document);
svgGenerator.setPaint(Color.black);

for (int i = 0; i < 10; i++) {
...
svgGenerator.fill(new Rectangle(p.x, p.y, 2, 2));
}

svgGenerator.setPaint(new Color(0, 0, 0, 0.2f));
for (int i = 0; i < 20; i++) {
CubicCurve2D curve = new CubicCurve2D.Float();
...
curve.setCurve(a.x, a.y, c.x, c.y, c.x, c.y, b.x, b.y);
svgGenerator.draw(curve);
}

...

OutputStream outputStream = new FileOutputStream(svgFileName);
Writer out = new OutputStreamWriter(outputStream, "UTF-8");
svgGenerator.stream(out, useCSS);
out.flush();
out.close();

给了我

<defs id="genericDefs"/>
<rect width="100%" height="100%" fill="white"/>
<g>
<g>
<rect x="699" width="2" height="2" y="350" style="stroke:none;"/>
<rect 
...
</g>
<g style="fill:rgb(0,0,0); fill-opacity:0.2; stroke-opacity:0.2; stroke:rgb(0,0,0);">
<path style="fill:none;" d="M699 350 C567 178 567 178 436 11"/>
<path 
...
</g>
</g>

我想为三个&#34; g&#34;提供单独的ID标签。蜡染创造的元素。我应该如何修改我的代码才能实现这个目标?

编辑:我使用@robert提供的提示,在创建所有元素后遍历DOM,使其工作。但这感觉像是一个丑陋的&#34;解决方案,有更优雅的东西吗?

Element root = svgGenerator.getRoot();
Element topG = (Element) root.getChildNodes().item(2);
topG.setAttribute("id", "allSVG");
Element rectangleG = (Element) topG.getChildNodes().item(0);
rectangleG.setAttribute("id", "rectangles");
Element pathG = (Element) topG.getChildNodes().item(1);
pathG.setAttribute("id", "paths");
...
svgGenerator.stream(root, out, useCSS, false);

1 个答案:

答案 0 :(得分:1)

“g”元素代表蜡染组,它们由 DOMTreeManager.appendGroup() 管理,因此每次蜡染创建一个新组(顶级组除外)时,它都会调用 DOMTreeManager.appendGroup()。您可以做的是通过注入您自己的 SVGGraphics2D 自定义版本来扩展 DOMTreeManager,该版本在每个组上设置 id。

public class IndexedSVGGraphics2D extends SVGGraphics2D {

    private Integer index = 0;

    public IndexedSVGGraphics2D(Document domFactory) {
        super(domFactory);
    }

    @Override
    protected void setGeneratorContext(SVGGeneratorContext generatorCtx) {
        // do the default work
        super.setGeneratorContext(generatorCtx);
        // do the magic
        this.domTreeManager = new DOMTreeManager(gc,
                generatorCtx,
                DEFAULT_MAX_GC_OVERRIDES){
            @Override
            public void appendGroup(Element group, DOMGroupManager groupManager) {
                // here setting any attribute which you need (in your case the id)
                group.setAttribute("id", String.valueOf(index++));
                super.appendGroup(group, groupManager);

            }
        };
        this.domGroupManager = new DOMGroupManager(gc, domTreeManager);
        this.domTreeManager.addGroupManager(domGroupManager);
    }
}

接下来只需在代码中使用 IndexedSVGGraphics2D 而不是 SVGGraphics2D

注意:如果您需要访问顶级组,只需使用 domTreeManager.getTopLevelGroup()