ele*_*que 0 java xml swing svg batik
我遇到了一个问题,过去两天我一直在苦苦挣扎。我有一个编译的程序,可以运行一些模拟并在 SVG 文件中可视化结果。该文件每 2 秒更换一次新文件,直到模拟完成。
为了可视化结果,我制作了一个 java swing 程序,它使用 batik 和 JSVGCanvas 来显示 svg 文件并每 2 秒更新一次。
我使用的代码是:
// In the main part of my code
svgCanvas = new JSVGCanvas();
oneLineInnerPanel.add("Center", svgCanvas);
(new Thread() {
@Override
public void run() {
try {
Thread.sleep(2000);
File f = new File("file_that_shows_simulation_still_running");
while (f.exists()) {
svgReloadButtonActionPerformed(null);
Thread.sleep(2000);
}
} catch (InterruptedException ex) {
Logger.getLogger(testUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
// -----------------------------------------------
private void svgReloadButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
svgCanvas.loadSVGDocument(SVGFile.toURL().toString());
} catch (MalformedURLException ex) {
Logger.getLogger(testUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,但每 30-40 更新一次,loadSVGDocument 会在模拟器写入文档时尝试读取文档,因此我收到 jdialog 错误:
XML 文档结构必须在同一实体内开始和结束。org.apache.batik.dom.util.SAXIOException:XML 文档结构必须在同一实体内开始和结束。在 org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:437) 在 org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:349) 在 org.apache.batik.dom .svg.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:200)在org.apache.batik.dom.svg.SAXSVGDocumentFactory.createSVGDocument(SAXSVGDocumentFactory.java:124)在org.apache.batik.bridge.DocumentLoader.loadDocument(DocumentLoader.java) :106)在org.apache.batik.swing.svg.SVGDocumentLoader.run(SVGDocumentLoader.java:84)
引起的:org.xml.sax.SAXParseException;系统ID:文件:/tmp/tempDir9189341730639722289/svgOut.svg;行号:272;列数:2;XML 文档结构必须在同一实体内开始和结束。在 org.apache.xerces.parsers.AbstractSAXParser.parse(未知来源) 在 org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:431) ... 5 更多
这并不影响整个过程,但它很丑陋。在整个模拟过程中我得到了 2-3 个这样的 jdialogs。我无法锁定文件 I/O,因为我无权访问模拟器代码。如果我仅从 java 锁定,模拟器会崩溃并表示无法访问该文件。
我想要的是,如果加载 svg 文件时出现错误,以某种方式在内部捕获它并且没有 jdialog。我可以接受每 30-40 次(60-80 秒)错过一次更新。
现在,JSVGCanvas 为您提供了提供用户代理并覆盖 displayError() 方法的选项,以按照您的意愿进行操作。我尝试过,但对话框仍然出现。问题是对话框不是由我提供的 svgUserAgent 生成的,而是由内部 BridgeUserAgent 生成的:
public JSVGComponent(SVGUserAgent ua, boolean eventsEnabled,
boolean selectableText) {
super(eventsEnabled, selectableText);
svgUserAgent = ua;
userAgent = new BridgeUserAgentWrapper(createUserAgent());
addSVGDocumentLoaderListener((SVGListener)listener);
addGVTTreeBuilderListener((SVGListener)listener);
addSVGLoadEventDispatcherListener((SVGListener)listener);
if (updateOverlay != null)
getOverlays().add(updateOverlay);
}
public void loadSVGDocument(String url) {
String oldURI = null;
if (svgDocument != null) {
oldURI = svgDocument.getURL();
}
final ParsedURL newURI = new ParsedURL(oldURI, url);
stopThenRun(new Runnable() {
public void run() {
String url = newURI.toString();
fragmentIdentifier = newURI.getRef();
loader = new DocumentLoader(userAgent);
nextDocumentLoader = new SVGDocumentLoader(url, loader);
nextDocumentLoader.setPriority(Thread.MIN_PRIORITY);
Iterator it = svgDocumentLoaderListeners.iterator();
while (it.hasNext()) {
nextDocumentLoader.addSVGDocumentLoaderListener
((SVGDocumentLoaderListener)it.next());
}
startDocumentLoader();
}
});
}
Run Code Online (Sandbox Code Playgroud)
谁能帮我摆脱这个困境吗?
提前致谢!
终于解决了问题。扩展JSVGCanvas,重写createUserAgent()方法来提供我自己的bridgeuseragent。此用户代理扩展了 JSVGCanvas 用户代理,但覆盖了 displayError 方法。这是代码:
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.util.XMLConstants;
/**
*
* @author
*/
public class myJSVGCanvas extends JSVGCanvas{
@Override
protected UserAgent createUserAgent() {
return new myCanvasUserAgent();
}
protected class myCanvasUserAgent extends CanvasUserAgent
implements XMLConstants {
/**
* Displays an error message in the User Agent interface.
*/
@Override
public void displayError(String message) {
if (svgUserAgent != null) {
super.displayError(message);
} else {
System.out.println(message);
// JOptionPane pane =
// new JOptionPane(message, JOptionPane.ERROR_MESSAGE);
// JDialog dialog =
// pane.createDialog(myJSVGCanvas.this, "ERROR");
// dialog.setModal(false);
// dialog.setVisible(true); // Safe to be called from any thread
}
}
/**
* Displays an error resulting from the specified Exception.
*/
@Override
public void displayError(Exception ex) {
if (svgUserAgent != null) {
super.displayError(ex);
} else {
ex.printStackTrace();
// JErrorPane pane =
// new JErrorPane(ex, JOptionPane.ERROR_MESSAGE);
// JDialog dialog = pane.createDialog(myJSVGCanvas.this, "ERROR");
// dialog.setModal(false);
// dialog.setVisible(true); // Safe to be called from any thread
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望它对某人有帮助。如果有人有更好的想法来处理这个问题,而不仅仅是隐藏它,我很高兴听到!