java使JSVGScrollPane内的JSVGCanvas与SVGDocument大小匹配
我在图表应用程序中显示SVG图形时遇到问题。画布采用其父组件的大小,而不是它包含的文档。大于此大小的文档不会完全呈现
案例
例如,我有一个621x621像素的图形
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" preserveAspectRatio="xMaxYMax slice" version="1.0">
<rect x="50" y="50" fill="white" width="20" height="20" stroke="black" stroke-width="1"/>
<rect x="600" y="600" fill="blue" width="20" height="20" stroke="black" stroke-width="1"/>
</svg>
它没有viewBox,因为它是动态创建的。当我创建文档时,我没有大小
我有一个JSVGCanvas
在一个JSVGScrollPane
内,滚动窗格的父级比文档小,比如说它的500x500像素
预期行为
启动应用程序时,可以看到适合500x500的图形部分。底层文档更大,所以有滚动条,可以向左和向下滚动121px
当增加框架的大小时,图形中越来越多的部分变得可见。当您将其增加到大于620x620px时,滚动条可能会完全消失
如果将面板缩小,然后再次显示文档,滚动条将重新出现
遇到的行为
启动应用程序时,可以看到适合500x500的图形部分。没有可见的滚动条
当面板变大时,画布会增加(其背景色),但图形不会延伸到初始500x500px之外的部分
当你把面板缩小到400x400时,滚动条确实会出现,但只允许我滚动100px。因此画布仍然是最初的500x500,而不是期望的621x621
示例
遇到的行为可以通过Batik存储库上的^{
如果在画布和滚动窗格中添加背景色,则整个框架为蓝色。因此,虽然画布的大小确实在增加,但它不会绘制超出其初始大小的任何内容
canvas.setBackground(Color.blue);
scroller.setBackground(Color.red);
我可以在调整面板大小后重置文档。这使得它可以重新绘制图形的可见部分,但滚动仍不能按预期工作,因为画布仍然只是可见部分的大小,而不是文档的大小。您可以通过将此侦听器添加到框架(或者我认为的任何其他面板)来测试这一点
class ResizeListener implements ComponentListener {
JSVGCanvas canvas;
URI url;
public ResizeListener(JSVGCanvas c, URI u) {
canvas = c;
url = u;
}
@Override
public void componentResized(ComponentEvent arg0) {
canvas.setURI(url.toString());
// Calling invalidate on canvas or scroller does not work
}
// ...
};
我已经读到我应该有一个viewBox,但是我的文档经常被重新创建(基于modelchange事件),当我创建文档时,我不知道如何获取viewBoxSVGDocument.getRootElement().getBBox();
通常给我null
。在没有提供viewBox的情况下,Batik代码中应该有回退,所以我希望这是可选的。另外,当我被平移到某个地方时,如果我更改文档,它应该保持这种平移
我希望我把问题说清楚了。当我期望JSVG类提供我想要的开箱即用的行为时,我是否对它们期望过高,或者我在这里遗漏了什么?有人能帮我找到解决办法吗
# 1 楼答案
我想我可能已经找到了解决办法。我需要设置文档的高度和宽度,而不是搞乱viewBox。设置了大小后,不需要查看框,滚动条可以按预期工作。如果我设置了viewbox,画布会不断缩放图像以使其适合
现在,为了更新大小,每当我更改可能会影响大小的dom时,我都会使用它
我在
UpdateManager
线程的之外执行此操作,在dom修改之后使用JSVGCanvas.setSVGDocument()
。当我试图通过UpdateManager
进行此操作时,它只更新了第一个更改。updatequeue的正确初始化可能可以解决这个问题,但由于我更改了很多文档,所以每次都可以重新开始我只剩下一个小问题。每当我设置新文档时,滚动位置都会重置。我尝试在操作之前进行转换,然后再重新应用,但这似乎不起作用
编辑+: 我通过替换文档的根节点,而不是替换整个文档,成功地解决了这个小问题。画布设置为documentstate ALWAYS_DYNAMIC。文档中的更改会立即应用,包括根节点的新大小(如上所述设置)。但由于文档没有完全替换,所以滚动状态保持不变
画布只有在完成文档呈现后才可以修改dom。我用SVGLoad监听器检测到了这一点