Hi Sascha, Thanks for taking a good look at the "Interactive Mode Switch" solution. I agree with your analysis. Setting the interactiveMode back to true in the flash runnable is a big improvement. It takes care of an issue that I have noticed with the selection background renderer drawing after the flash. SelectionBackgroundRenderer's useImageCaching() method simply returns true, and so is unaffected by the modified version of RenderManager.createRender()'s call to setMaxFeatures(Integer.MAX_VALUE).
I'm hoping someone will verify that this solution works for printing plugins. I also have an idea for improving the quality of the generated SVG. I'll create a new post, but it involves fixing BasicStyle.setLineWidth(int lineWidth) to use a float instead of an int and changing setLineWidth(1) to setLineWidth(0.1) or something smaller in the constructor. regards, Larry Becker On 6/24/07, Sascha L. Teichmann <[EMAIL PROTECTED]> wrote: > Hi Larry, > > I was so happy that you proposed a 'minimal inversive' solution, but I > think it needs at least some tweaking. > > Let's have a look at the relevant part of ZoomToSelectedItemsPlugIn.zoom(): > > 1 -- panel.getRenderingManager().setInteractiveMode(false); > 2 -- panel.getViewport().zoom(proposedEnvelope); > 3 -- SwingUtilities.invokeLater(new Runnable() { > public void run() { > try { > flash(geometries, panel); > } catch (NoninvertibleTransformException e) { > } > }}); > 4 -- panel.getRenderingManager().setInteractiveMode(true); > > After switching to non-interactive mode (1) all Renderer Runnables > produced by the RenderingManager are directly executed in the > event dispatch thread. This would be done in a render() method > of JUMP's RenderingMaanager. Unfortunately this will not happen! > > If you call the Viewport.zoom method (2) the last thing inside this is > a repaint() against the LayerViewPanel. This repaint() lets the > Swing(!) RenderingManager of this component enqueue a Runnable > to the event display thread for later execution. Inside this > Runnable the render*() calls of *JUMPs will be executed. But for > the moment this is only scheduled. > > After you've enqueued the flash Runnable (3) the internal event > dispatch queue will look like the following. > > [a: Runnable from repaint -- render*()], [b: Runnable to flash] > > This would be fine too because _iff_ the RenderingManager would > be in the non-interactive mode at the time of execution of a. > Then the Renderers would be executed directly via > GUIUtil.invokeOnEventThread(). So they would be executed before b. > > But now the problem: Now you are doing 4, switching JUMP's > RenderingManager directly back to interactive mode. > The jobs a and b are not executed yet. > So when they got executed after the end of > ZoomToSelectedItemsPlugIn.zoom() the RenderingManager is back in > interactive mode and the Renderer Runnables > are not executed with GUIUtil.invokeOnEventThread(). > > To fix this I would place the 5 call inside the flash Runnable directly > before the flash() call too ensure that JUMPs rendering manager stays in > non-interactive mode as long as needed. > > This observations are made under the assumption that > ZoomToSelectedItemsPlugIn.zoom() runs in the event dispatch thread. > If this is not the case the results are not predictable because the > threads will work against each other and race conditions may occur. > > But as always: I may be wrong with my analysis and so comments > and critics are welcome. :-) > > I'm still a bit concerned that the hole expensive rendering is done > inside the event dispatch thread. I have to test if this may lead to > trouble elsewhere. > > Stay tuned, > Sascha > > Sascha L. Teichmann schrieb: > > Hi Larry, > > > > this definitely a step into the right direction. :-) > > > > Using the event/display thread to serialize the > > renderers in the non-interactive mode is a good idea. > > Your code looks fine but I will think about the > > consequences (blocking GUI, etc.). Of course I > > will test it, too. ;-) > > > > Regards, Sascha > > > > Larry Becker schrieb: > >> The purpose of this thread is to document a problem with RenderManager > >> and to propose solutions. > >> > >> The good news: > >> > >> RenderManager is optimized for the most responsive interactive GUI > >> experience. It uses multiple threads, image caching, and timed > >> refresh operations to ensure that the user's perception is that they > >> never have to wait. IMO JUMP is unrivaled in this respect. > >> > >> The bad news: > >> > >> The original JUMP design did not including printing support. Saving a > >> screen image was the only option. Now we have many options supporting > >> printing, SVG, PDF, and image export. This is great, but all of them > >> have to work around RenderManager issues to ensure proper results. > >> Sometimes a long user-specified delay while WMS or server layers > >> finish rendering is necessary. This looks unprofessional and is > >> ultimately unreliable. > >> ---------------------------------------- > >> > >> Here is the preferred solution as I see it (call it the "Interactive > >> Mode Switch" solution): > >> > >> Make a modification to the RenderManager class to include a new > >> property called interactiveMode with associated getters and setters. > >> The interactiveMode property defaults to true. Printing code and > >> other routines that need batch oriented rendering will need to bracket > >> their rendering code with calls to setInteractiveMode(false) and > >> setInteractiveMode(true). In between the calls, rendering operations > >> are guaranteed to be done on the same thread and block until they > >> complete. > >> > >> How this is accomplished: > >> > >> Again, making modifications only to RenderManager, make the following > >> changes: > >> > >> 1. In createRenderer() if interactiveMode is true, it should > >> setMaxFeatures for the Renderer to the maximum integer. This will > >> disable image caching, causing renderers to paint directly to the > >> graphics context. > >> > >> 2. in render() if interactiveMode is true, it should run the Renderer > >> on the event thread instead of using the ThreadQueue. Also it should > >> not start a repaint timer. > >> > >> These changes effectively eliminate any unsynchronized rendering from > >> RenderManager. See the attached copy of RenderManager for details. > >> ----------------------------------------------------- > >> > >> For interactive plug-ins like ZoomToSelectedItems that also need to > >> control rendering order so that the flash operation is synchronized. > >> For ZoomToSelectedItems, in addition to bracketing rendering code with > >> sets, it is also necessary to use invokeLater() on the flash() method > >> so that it will be executed in order with the panel component update. > >> > >> I have tested this solution on both OpenJump and SkyJUMP and it seems > >> to solve the ZoomToSelectedItems flash issue (see attached file for > >> details). I tested on my usual P4 2.4GHz and also on a 1.5GHz Athlon. > >> More testing is needed to determine how well it meets the needs of > >> printing plug-ins. > >> > >> This solution has the advantage that JUMP continues to behave exactly > >> as before until you set the interactiveMode to false. No refactoring > >> of interactive rendering code is necessary. > >> > >> regards, > >> Larry Becker > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Jump-pilot-devel mailing list > Jump-pilot-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel > -- http://amusingprogrammer.blogspot.com/ ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ Jump-pilot-devel mailing list Jump-pilot-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel