I've met a problem and I've been struggling last 2 days. I have a compiled
program that runs some simulations and visualizes the results in an SVG
file. The file is replaced every 2 seconds with a new one, until the
simulation is done.

Wanting to visualize the results, I made a java swing program which uses
batik and JSVGCanvas to display the svg file and update it every 2 seconds.
The code I use is:

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

It works fine with the exception that every 30-40 updates, it happens that
the loadSVGDocument tries to read the document while it's being written by
the simulator and thus I get a jdialog error:
XML document structures must start and end within the same entity.
org.apache.batik.dom.util.SAXIOException: XML document structures must
start and end within the same entity.
at
org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:437)
 at
org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:349)
at
org.apache.batik.dom.svg.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:200)
 at
org.apache.batik.dom.svg.SAXSVGDocumentFactory.createSVGDocument(SAXSVGDocumentFactory.java:124)
at
org.apache.batik.bridge.DocumentLoader.loadDocument(DocumentLoader.java:106)
 at
org.apache.batik.swing.svg.SVGDocumentLoader.run(SVGDocumentLoader.java:84)
Caused by: org.xml.sax.SAXParseException; systemId:
file:/tmp/tempDir9189341730639722289/svgOut.svg; lineNumber: 272;
columnNumber: 2; XML document structures must start and end within the same
entity.
 at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at
org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:431)
 ... 5 more

This doesn't affect the whole procedure, but it's ugly. I get 2-3 of these
jdialogs throughout the simulation. I cannot lock the file I/O, because I
don't have access to the simulator code. If I lock from java only, the
simulator crashes saying it cannot access the file.

What I want is that if there is an error while loading the svg file to
somehow catch it internally and not have a jdialog. I can accept missing an
update every 30-40 times (60-80 secs) instead of getting the jdialogs.

Now, JSVGCanvas gives you the option to provide a useragent and overwrite
the displayError() method to do as you like. I tried that but the dialogs
still occur. The problem is that the dialogs are not produced by the
svgUserAgent I provide but by an internal 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();
                }
            });
    }

I use the batik-1.7 and JDK 1.7. The same problem exists both on Windows 7
and on Debian Wheezy. Can anyone help me get out of this mess, please?

This has been cross-posted on
http://stackoverflow.com/questions/21218720/jsvgcavas-bridgeuseragent-displayerror-override

Thanks in advance,
Petros

Reply via email to