JSVGCavas BridgeUserAgent переопределение displayError()
Я столкнулся с проблемой, и я боролся последние 2 дня. У меня есть скомпилированная программа, которая запускает некоторые симуляции и визуализирует результаты в файле SVG. Файл заменяется каждые 2 секунды на новый, пока симуляция не будет завершена.
Желая визуализировать результаты, я создал java-программу, которая использует батик и 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);
}
}
Он работает нормально, за исключением того, что каждые 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.jatig.ached. atb. atb. atb. atb.basek) .svg.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:200) в org.apache.batik.dom.svg.SAXSVGDocumentFactory.createSVGDocument(SAXSVGDocumentFactory.jocumentLo.batio.bb.java_jb::106) at org.apache.batik.swing.svg.SVGDocumentLoader.run(SVGDocumentLoader.java:84)
Вызывается: org.xml.sax.SAXParseException; systemId: file:/tmp/tempDir9189341730639722289/svgOut.svg; номер строки: 272; columnNumber: 2; Структуры XML-документов должны начинаться и заканчиваться в одной и той же сущности. в org.apache.xerces.parsers.AbstractSAXParser.parse(неизвестный источник) в org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:431) ... еще 5
Это не влияет на всю процедуру, но это ужасно. Я получаю 2-3 таких журнала во время симуляции. Я не могу заблокировать файловый ввод / вывод, потому что у меня нет доступа к коду симулятора. Если я блокирую только из Java, симулятор падает, говоря, что он не может получить доступ к файлу.
Я хочу, чтобы при загрузке файла svg возникла ошибка, чтобы он каким-то образом перехватил его и не имел jdialog. Я могу принять пропущенное обновление каждые 30-40 раз (60-80 секунд) .
Теперь JSVGCanvas дает вам возможность предоставить useragent и переписать метод 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();
}
});
}
Может кто-нибудь помочь мне выбраться из этого беспорядка, пожалуйста?
Заранее спасибо!
1 ответ
Наконец-то решена проблема. Расширенный JSVGCanvas, переопределите метод createUserAgent(), чтобы предоставить мой собственный бридж-агент. Этот пользовательский агент расширяет пользовательский агент 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
}
}
}
}
Надеюсь, это кому-нибудь поможет. Если у кого-то есть лучшая идея для решения проблемы, чем просто ее скрыть, я буду рад это услышать!