Thomas DeWeese wrote:
>> 1. Swing event triggers canvas.setSVGDocument(firstDoc). >> >> 2. manipulate firstDoc's DOM (in UpdateManger's thread) in response to >> Swing mouse clicks, etc. >> >> 3. Swing event calls canvas.getSVGDocument() to get the modified >> firstDoc back, and then canvas.setSVGDocument(secondDoc). > > > Hi George, > > So are we OK up to here?
Yes.
> Well a stack trace would have helped to identify why you get the > NPE. But my assumption is that you are modifying the firstDoc > before the UpdateManager that has been managing it is shut down.
I agree, it's because I am modifying the DOM outside of the UpdateManager's thread. Here's a stack trace.
java.lang.NullPointerException at org.apache.batik.bridge.CSSUtilities.convertDisplay(Unknown Source) at org.apache.batik.bridge.AbstractGraphicsNodeBridge.getDisplay(Unknown Source) at org.apache.batik.bridge.GVTBuilder.build(Unknown Source) at org.apache.batik.bridge.SVGGElementBridge.handleElementAdded(Unknown Source) at org.apache.batik.bridge.SVGGElementBridge.handleDOMNodeInsertedEvent(Unknown Source) at org.apache.batik.bridge.BridgeContext$DOMNodeInsertedEventListener.handleEvent(Unknown Source)
Hmm you seem to be getting exceedingly unlucky here. :) The NPE is caused by the BridgeContext dispose method disposing of the CSSEngine (no display property anymore). But the dispose of the CSSEngine is done _after_ the BridgeContext DOM listeners are removed from the Document.
> There is a set of UpdateManagerEvents that you can listen to, in > order to know when it has shut down.
Which thread are the UpdateManagerEvents fired in?
The UpdateManager RunnableQueue thread, not Swing, but see below...
> Well it sounds to me like you need to queue these user events until > the system can catch up with them. I would suggest using something > like our RunnableQueue to do this.
Yeah, this is what I am afraid of. It would really complicate things to propagate the "queueness" of the canvas to the rest of our app. I'm trying to isolate all of the batik event handling to my canvas extension, and keep it as much a black box as possible. We need synchronous behavior for the rest of the app (load the doc, modify it, unload it, install next doc.)
Well just my 2c but blocking the Swing thread is really bad behavior for an application. If you want to 'suspend' user interaction that is fine but don't block the Swing thread.
> The first thing the runnable does is check that the canvas is > 'stable' (Which can block because we are out of the Swing thread) > then it can install the next document.
Ah, so maybe the UpdateManager's events are not fired from the Swing thread after all?
Even if it were called in the Swing thread you can have a small class that just tracks the 'state' of the Canvas. Heck the modification of the document to be written can be delayed indefinitely. So when I went to set the new document I would do something like:
final Document oldDoc = canvas.getSVGDocument(); final UpdateManager um = canavs.getUpdateManager(); um.addUpdateManagerListener(new UpdateManagerAdapter() { public void managerStopped(UpdateManagerEvent e) { um.removeUpdateManagerListener(this); prepDocument(oldDoc); writeDocument(oldDoc); } }; canvas.setSVGDocument(newDoc);
This Listener will 'hang out' until the UpdateManager stops then it will prep the old doc for write, then write it, no blocking or anything messy.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]