George Armhold wrote:
I'm trying to resolve a threading problem in my app. I'm using JSVGComponent to display an SVG doc and dynamically update it in response to AWT events (mouse drag/release results in adding <line> elements to the DOM.) This generally works well. However I occasionally run into a problem when loading a new document into the JSVGComponent when DOM updates are apparently in-progress. The scenario is the following:
- document load initiated via JSVGComponent.loadSVGDocument().
- I get an UpdateManagerListener event indicating that the doc is available for updates, so I enable my drawing code.
- MouseDown event; user draws some line segments via the mouse in AWT graphics.
- MouseReleased event; I add all my <line> elements to the document. I do this in the UpdateManager's RunnableQueue via something like the following:
// running in Swing/AWT thread after MouseReleased event UpdateManager um = getUpdateManager(); RunnableQueue rq = um.getUpdateRunnableQueue(); rq.invokeAndWait(new Runnable() { public void run(){ // add my elements to the DOM } });
- user initiates loading of a new SVG doc by clicking a Swing button.
This usually works. However sometimes I find that getUpdateManager()
returns null, or that the RunnableQueue is not started.
This would indicate to me that the MouseReleased code is running after the load event (the getUpdateManager call is before the call to invokeAndWait so it's hard to blame a null return from getUM on invokeAndWait :). I would suggest inserting System.err messages so you can find out which code runs when in these cases. The JSVGCanvas tries to be very good about this cases so even if you did an invokeLater it should wait until your runnable ends before disposing of the document.
Just picking on words here you say "after MouseReleased event" is this happening _in_ the mouseRelease callback, or is it code triggered by the mouse release callback?
This tends to happen when the user draws LOTS of line segments, resulting in many DOM elements to be added. I *think* that what's happening is that a new SVG doc load request is being initiated by the user before the elements are finished being added to the DOM in my run() method. This is a bit baffling to me, as the Swing/AWT thread should block on invokeAndWait() before processing the "load new document" button click. This problem is hard to reproduce because of the timing involved. Also sometimes I find that I am able to hang the entire GUI by this process.
So I guess my question is the following: how can I dynamically and
synchronously update the DOM via Swing/AWT events? I need to block
until the update completes.
The above should do it (although I really suspect that you don't need to block in this case if you are just throwing away the document anyway).
Is invokeAndWait "bad"? There is some discussion about this in the following thread:
http://koala.ilog.fr/cgi-bin/batik-users-search-grep?rule=ci&target=invokeAndWait+%7C+invokeLater
Yes invokeAndWait from the AWT thread is bad because some DOM calls require calling back to the AWT thread which will cause a deadlock. You can safely use it from a third thread. But this is _not_ the issue you are having (well it might be the freeze issue).
Thanks very much for your time.
PS: this is all with Batik-1.5 built from CVS on 20-Aug-2003 and JDK 1.4.2.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]