2014-01-19 48 views
0

我遇到了一個問題,我一直在掙扎最後2天。我有一個編譯好的程序,運行一些模擬,並將結果可視化爲SVG文件。該文件每2秒更換一次,直到模擬完成。JSVGCavas BridgeUserAgent displayError()覆蓋

想要可視化結果,我做了一個java swing程序,它使用蠟染和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 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

這並不影響整個過程,但它是醜陋的。在整個模擬過程中,我會得到2-3個這樣的jdialog。我無法鎖定文件I/O,因爲我無法訪問模擬器代碼。如果我只從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(); 
      } 
     }); 
} 

誰能幫助我走出這個爛攤子嗎?

在此先感謝!

回答

3

終於解決了這個問題。擴展JSVGCanvas,重寫createUserAgent()方法以提供我自己的bridgeuseragent。這個useragent擴展了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 
     } 
    } 
}  
} 

希望它有助於某人。如果任何人有更好的主意來處理這個問題,而不是隱藏它,我會很高興聽到它!

+0

謝謝,它的工作原理,它也是一個聰明的解決方案。 – csadan