Wilkins, Rob wrote:
I added slightly more trace code to the GVTTreeRendererAdapter callbacks and more to the paint method in the objects we are drawing on top of JSVGCanvas. The call to scale the objects is now being carried out in an overridden setRenderingTransform() as you suggested (just prior to the call to super.setRenderingTransform()).
The results of the tracing for a single zoom are:
MapJSVGCanvas.mousePressed() : transform is AffineTransform[[1.25, 0.0, 0.0], [0.0, 1.25, 0.0]] MapJSVGCanvas.transformNodes() : transform is AffineTransform[[1.25, 0.0, 0.0], [0.0, 1.25, 0.0]] Found a GfxNode to scale!!!
It might be useful to track calls to setRenderingTransform (both the one and two arg versions, see below).
GfxNode::paint() x 0.0 y 0.0 width 83.0 height 54.0 GfxNode::paint() x 0.0 y 0.0 width 83.0 height 54.0 GVTTreeRendererAdapter::gvtRenderingStarted() GfxNode::paint() x 0.0 y 0.0 width 83.0 height 54.0 GfxNode::paint() x 0.0 y 0.0 width 83.0 height 54.0 GVTTreeRendererAdapter::gvtRenderingStarted() GfxNode::paint() x 0.0 y 0.0 width 83.0 height 54.0 GVTTreeRendererAdapter::gvtRenderingCompleted()
Note that the first Started event has no matching Completed Event this probably indicates that it was interrupted. A common cause of interruption is setting the rendering transform. Which is why I would be curious if setRenderingTransform is being called multiple times.
I'm not quite sure why the paint routine is being called more than once. But the above shows what I was trying to say about the double rendering of the JSVGCanvas object.
Yes.
The objects are being scaled by manipulation of their bounding box (calls to getBounds() and setBounds()).
Ok, I was thinking you were playing with the affine that would get passed into there paint calls. But as you say below I'm sure that modifying the bounds of these child objects will cause the parent to render.
As far as I can see we are doing nothing explicitly to trigger the repaints of anything. I presume that calling JSVGCanvas.setRenderingTransform() causes it to be re-rendered and that changing the location of the JComponent based objects causes them to move (and I guess causes the parent JSVGCanvas object to be re-rendered once more).
Since 1.1.1 we added a new version of 'setRenderingTransform' that takes a boolean as a second parameter. If the second parameter is false then it will not cause a re-render. The single argument version now just calls the two argument version with 'true' for the second arg.
I can see what you mean in that you think the objects would be rendered again and the above trace output shows that they are.
I suppose the one question I'm really interested in is why the code worked in Batik 1.1.1 and yet not in Batik 1.5.
Well many, many things changed in rendering between Batik 1.1.1 and 1.5 so this sort of thing isn't too surprising to me. One thing that occurred to me is are you making modifications to the SVG document to 'record' the change in view (like updating the viewBox attribute)? If so it is possible (likely) that because 1.5 supports dynamic updates this is the source of the double transform (however I strong suspect that the problem is someone calling setRenderingTransform twice).
I'll look into the custom scroll pane in v1.5.1rc2 but I think I'll still have the same double transform problem.
Thanks again for your help,
Well good luck!
Rob
-----Original Message-----
From: Thomas DeWeese [mailto:[EMAIL PROTECTED] Sent: 14 January 2004 12:23
To: [EMAIL PROTECTED]
Subject: Re: Displaying Java objects on top of JSVGCanvas objects
Hi Rob,
Wilkins, Rob wrote:
I've inherited a Java GUI that uses the JSVGCanvas object (through a derived class) inside a JScrollPane. Objects which are derived from JComponent are then added to the JSVGCanvas object using the JSVGCanvas.add() method.
Hmm, this is pretty far out there. One thing I might note is that in Batik 1.5.1rc2 there is now a custom Scroll Pane that is much more efficient with memory than using a standard JScrollPane especially when zooming in (with the standard scroll pane the canvas would end up allocating an offscreen buffer the full size of the canvas at what ever zoom factor - this could be _huge_).
The user can zoom in and out of the SVG. This is implemented by a mouse event handler on the JSVGCanvas derived class which calls JSVGCanvas.getRenderingTransform(), manipulates the AffineTransform then applies it by calling JSVGCanvas.setRenderingTransform().
Ok this seems pretty normal.
The objects placed on top of the JSVGCanvas (via calls to add()) are then scaled using the same transform via a code in the gvtRenderingCompleted() event handler (although this code has also been called from gvtRenderingStarted() and also in the mouse handler (where the transform is being manipulated) during attempts to fix the problems we are encountering).
So this part seems a little odd to me. In particular gvtRenderingCompleted is not part of the normal AWT component painting mechanisms, so it is unclear to me exactly what you are doing here. Are you just notifying the other components what the new transform is? If so why not do that in an override of setRenderingTransform?
The code all worked in Batik v1.1.1 and as the user zoomed in and out of the SVG the objects on top were also scaled to keep them synchronised with the SVG.
However when we moved to Batik v1.5 (in an effort to reduce the amount of memory that appeared to be leaked when loading new SVGs and zooming them) we noticed that the SVG and the objects were no longer being synchronised when the SVG was being manipulated. After a bit of investigation it appears that the scaling of the objects is causing the SVG to be re-rendered such that the following appears to be happening:
Render the SVG at the new scale.
Render the objects at the new scale.
Render the SVG at the new scale again.
To me clear on what we mean by 'render' I want to clarify to steps to display. Rendering - which calls gvtRenderingCompleted and 'painting' which is done in paintComponent. Given this terminology is the SVG rendered twice or rendered once and 'painted' twice.
Also the above would indicate to me that the objects don't show because the SVG would be drawn over them. I take it there is also a second Render objects at new scale?
This also happened in Batik v1.1.1, however the difference between the two versions appears to be that when the above sequence occurs in v1.1.1 the two renderings of the SVG occur at the same scale (say 1.25 times the original). However when this is executed in v1.5 the SVG is first rendered at a scale of 1.25 then at a scale of (1.25 * 1.25). The objects and the SVG are therefore being rendered at different scales (1.25 and 1.25^2) respectively. This can be further shown by setting the scale to 1 which allows the objects and the SVG to be rendered at the same scale since 1^2=1.
I suspect that however you are scaling the objects is now being applied to the JSVGCanvas when it calls paintComponent. The whole AWT paint chain has never been my strong suite so I can't really tell you what methods should be overridden and how to do what you want, but I think you really need to override what ever method in JComponent draws the child components so you can set transform just for them.
Our ideal solution would be to prevent the re-rendering of the SVG (which we presume is being triggered by the rendering of the objects on top of it).
Once again it is important to know if we are talking about rendering or painting. I would be curious to know how you are triggering the repainting of the child Objects when the transform changes.
However if we should be drawing the objects using some other mechanism we would like to know how to do this. I looked through the archives of this group and I get the impression that I should be rendering all the objects using some form of overlay object. However the objects have context menus and the user can interact with them to move them and resize them so I would need to be able to provide this type of functionality using the alternative object rendering solution if one is suggested.
I've tried some of the methods on JSVGCanvas that would appear to disable it/enable it around the calls to scale the objects but the above sequence still appear to occur.
My guess is that this code is the problem code but you don't really give any details so I can't really help.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
*********************************************************************************** This email, its content and any attachments is PRIVATE AND CONFIDENTIAL to TANDBERG Television. If received in error please notify the sender and destroy the original message and attachments.
www.tandbergtv.com ***********************************************************************************
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]