2014-01-19 1 views
0

Я столкнулся с проблемой, и я боролся последние 2 дня. У меня есть скомпилированная программа, которая запускает некоторые симуляции и визуализирует результаты в SVG-файле. Файл заменяется каждые 2 секунды новым, пока симуляция не будет выполнена.JSVGCavas BridgeUserAgent displayError() override

Желая визуализировать результаты, я создал программу 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); 
    } 
} 

Он отлично работает, за исключением, что каждые 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 из этих jdialogs во время моделирования. Я не могу заблокировать ввод/вывод файлов, потому что у меня нет доступа к коду симулятора. Если я блокирую только из 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

Окончательно решена проблема. Extended JSVGCanvas, переопределите метод createUserAgent(), чтобы предоставить собственный мост. Этот 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