You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by Reinhard Brandstädter <r....@gmx.at> on 2003/08/11 16:46:30 UTC

Wierdness in appending elements to SVGDocument

Hi!

I've encountered a problem wich I can't find a solution for, although 
I've tried some time now. Maybe it's just too easy and I'm thinking to 
complicated.

I've got a JDialog which contains a JSVGCanvas created the following way 
(copied from the examples):

..
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
doc = impl.createDocument(svgNS, "svg", null);
Element svgRoot = doc.getDocumentElement();
svgRoot.setAttributeNS(null, "overflow", "visible");
...
jSVGCanvas1.setDocumentState(JSVGComponent.ALWAYS_DYNAMIC);
jSVGCanvas1.setSVGDocument( (SVGDocument) doc);
jScrollPane1.getViewport().add(jSVGCanvas1, null);

--------
later on in this GUI I start a simple Timer thread, that gets Objects 
from a Queue. These Objects will later on create simple SVG Element 
Document Nodes so I create Runnables that are added to the UpdateQueue.
--------

timer = new Timer(200, new ActionListener() {
   public void actionPerformed(ActionEvent evt) {
     ... unrelated calculations ...
     GraphicalObject g = ecfg.getEventRepresentation();
     g.setPosition(x, y);
     jSVGCanvas1.getUpdateManager().getUpdateRunnableQueue(). \
       invokeLater(new SVGUpdate(jSVGCanvas1.getSVGDocument(),g));
   }
});

--------
The Runnable Object added to the UpdateManager looks like this:
--------

public class SVGUpdate implements Runnable {
   GraphicalObject g;
   SVGDocument doc;

   public SVGUpdate(SVGDocument svgdoc, GraphicalObject g) {
     this.g = g;
     doc = svgdoc;
   }

   public void run() {
     g.append(doc);
   }
}

--------
The getSVGElement Method that should (and does) produce a valid element 
and the append Method that is called from the UpdateManager Runnable.
--------

public Element getSVGElement(SVGDocument doc) {
   Element circle = doc.createElementNS(svgNS, "circle");
//DOMImplementation.SVG_NAMESPACE_URI= ^^^^^
   circle.setAttributeNS(null, "cx", String.valueOf(x));
   circle.setAttributeNS(null, "cy", String.valueOf(y));
   circle.setAttributeNS(null, "r", String.valueOf(r));
   circle.setAttributeNS(null, "style", "fill:"+fillcolor);
   return circle;
}

public void append(SVGDocument doc) {
   doc.getRootElement().appendChild(getSVGElement(doc));
}

--------
And now comes the part that I can't understand. When running the 
Application dynamically generated Elements (by calling getSVGElement()) 
are displayed in the JSVGCanvas of my Dialog, but a few are missing. It 
starts with missing a few and later on even more Elements are not 
showing up. Although the UpdateManager processes all of them (counted 
debugg outputs in the run() method of SVGUpdate. (560 Elements processed 
by the Timer and 560 finished run() methods)

I've dumped the generated SVG file from the JSVGCanvas, to download here:
http://www.gup.uni-linz.ac.at/~rbrand/dump-display-but-missing.svg

But what really gives me to thing is the fact that if I change the 
global String variable "svgNS" used in the getSVGElement() Method to 
something useless or even an emty String "" the Document doesn't get 
displayed in the JSVGCanvas during runtime at all, but if I dump the 
file again it's correct without missing Elements, to download here:
http://www.gup.uni-linz.ac.at/~rbrand/dump-nodisplay-nomissing.svg

So how can this happen? As the second version without displaying during 
runtime shows all Elements are processed sucessfully, but how the heck 
can it happen that they are not displayed in the first version?

hmmm?

Thanks for any hints!
Reinhard
-- 
Reinhard Brandstaedter   r.brandstaedter@gmx.at  GPG: 0x033B81DB
-    Student of Computer Science - J.K. University of Linz     -
-        <ICQ: 73059068>    <Mobile: +43 699 12419541>         -
-                  http://adelaide.dnsalias.net                -


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Re: Wierdness in appending elements to SVGDocument

Posted by Thomas DeWeese <Th...@Kodak.com>.
Reinhard Brandstädter wrote:
> Thomas DeWeese wrote:
> 
>> Hi Reinhard,
>>
>>   The difference is that when you use "" in DOM they aren't SVG elements
>> but when seirialized they 'become' SVG elements because they have no
>> prefix and the default namespace is SVG.  Thus we must conclude the
>> issue is mostly likely the additional time incurred in repainting
>> the canvas when SVG elements are added to the DOM.
>>
>>   From this I conclude that your GraphicalObject returned by
>> 'ecfg.getEventRepresentation()' is reused, and hence you
>> end up setting the position of the previous circle if the
>> runnable hasn't completed yet.  I've confirmed this by
>> checking that there are infact 280 circles in the 'missing'
>> SVG file and some of them have duplicate locations.
> 
> Good point, I didn't think of that. Although I think the ecfg Object is 
> returned from a Buffer and so should be a individual and different 
> Object everytime, so should be the Graphical Object.
> But anyway I'll try to clone the Object for the Update Thread.
> 
> I'm thinking of an another solution too, instead of using the 
> invokeLater() method of the RunnableQueue, I'll try to use 
> invokeAndWait().

    There should be no problem with this.  Once does need to be careful
using this from the swing event thread.

> Is there another safe way to update the document without the 
> RunnableQueue, as far as I can see the updatethreads are invoked at any 
> point. I would prefer a exect point of time (controllable by me or the 
> timer)

   The short answer is no, the only safe way to update the document
is in the update thread.  I guess the real question is what
would it mean to say an 'exact point of time'?  What if the
document is being modifed from another timer, or for display?
Someone needs to be delayed.  The Update manager tries to
run your runnable as soon as possible - I don't know that you
can do any better given the need to synchronize.

   The FAQ goes into a bit more detail why Batik it architected
this way.



---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Re: Wierdness in appending elements to SVGDocument

Posted by Reinhard Brandstädter <r....@gmx.at>.
Thomas DeWeese wrote:
> Hi Reinhard,
> 
>   The difference is that when you use "" in DOM they aren't SVG elements
> but when seirialized they 'become' SVG elements because they have no
> prefix and the default namespace is SVG.  Thus we must conclude the
> issue is mostly likely the additional time incurred in repainting
> the canvas when SVG elements are added to the DOM.
> 
>   From this I conclude that your GraphicalObject returned by
> 'ecfg.getEventRepresentation()' is reused, and hence you
> end up setting the position of the previous circle if the
> runnable hasn't completed yet.  I've confirmed this by
> checking that there are infact 280 circles in the 'missing'
> SVG file and some of them have duplicate locations.

Good point, I didn't think of that. Although I think the ecfg Object is 
returned from a Buffer and so should be a individual and different 
Object everytime, so should be the Graphical Object.
But anyway I'll try to clone the Object for the Update Thread.

I'm thinking of an another solution too, instead of using the 
invokeLater() method of the RunnableQueue, I'll try to use invokeAndWait().
Is there another save way to update the document without the 
RunnableQueue, as far as I can see the updatethreads are invoked at any 
point. I would prefer a exect point of time (controllable by me or the 
timer)

-- 
Reinhard Brandstaedter   r.brandstaedter@gmx.at  GPG: 0x033B81DB
-    Student of Computer Science - J.K. University of Linz     -
-        <ICQ: 73059068>    <Mobile: +43 699 12419541>         -
-                  http://adelaide.dnsalias.net                -


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Re: Wierdness in appending elements to SVGDocument

Posted by Thomas DeWeese <Th...@Kodak.com>.
Hi Reinhard,

   The difference is that when you use "" in DOM they aren't SVG elements
but when seirialized they 'become' SVG elements because they have no
prefix and the default namespace is SVG.  Thus we must conclude the
issue is mostly likely the additional time incurred in repainting
the canvas when SVG elements are added to the DOM.

   From this I conclude that your GraphicalObject returned by
'ecfg.getEventRepresentation()' is reused, and hence you
end up setting the position of the previous circle if the
runnable hasn't completed yet.  I've confirmed this by
checking that there are infact 280 circles in the 'missing'
SVG file and some of them have duplicate locations.

   I suggest you have getEventRepresentation return a new
graphical object each time, or make x,y parameters
to SVGUpdage.


Reinhard Brandstädter wrote:

> timer = new Timer(200, new ActionListener() {
>   public void actionPerformed(ActionEvent evt) {
>     ... unrelated calculations ...
>     GraphicalObject g = ecfg.getEventRepresentation();
>     g.setPosition(x, y);
>     jSVGCanvas1.getUpdateManager().getUpdateRunnableQueue(). \
>       invokeLater(new SVGUpdate(jSVGCanvas1.getSVGDocument(),g));
>   }
> });
> 
> --------
> The Runnable Object added to the UpdateManager looks like this:
> --------
> 
> public class SVGUpdate implements Runnable {
>   GraphicalObject g;
>   SVGDocument doc;
> 
>   public SVGUpdate(SVGDocument svgdoc, GraphicalObject g) {
>     this.g = g;
>     doc = svgdoc;
>   }
> 
>   public void run() {
>     g.append(doc);
>   }
> }
> 
> --------
> The getSVGElement Method that should (and does) produce a valid element 
> and the append Method that is called from the UpdateManager Runnable.
> --------
> 
> public Element getSVGElement(SVGDocument doc) {
>   Element circle = doc.createElementNS(svgNS, "circle");
> //DOMImplementation.SVG_NAMESPACE_URI= ^^^^^
>   circle.setAttributeNS(null, "cx", String.valueOf(x));
>   circle.setAttributeNS(null, "cy", String.valueOf(y));
>   circle.setAttributeNS(null, "r", String.valueOf(r));
>   circle.setAttributeNS(null, "style", "fill:"+fillcolor);
>   return circle;
> }
> 
> public void append(SVGDocument doc) {
>   doc.getRootElement().appendChild(getSVGElement(doc));
> }
> 
> --------
> And now comes the part that I can't understand. When running the 
> Application dynamically generated Elements (by calling getSVGElement()) 
> are displayed in the JSVGCanvas of my Dialog, but a few are missing. It 
> starts with missing a few and later on even more Elements are not 
> showing up. Although the UpdateManager processes all of them (counted 
> debugg outputs in the run() method of SVGUpdate. (560 Elements processed 
> by the Timer and 560 finished run() methods)
> 
> I've dumped the generated SVG file from the JSVGCanvas, to download here:
> http://www.gup.uni-linz.ac.at/~rbrand/dump-display-but-missing.svg
> 
> But what really gives me to thing is the fact that if I change the 
> global String variable "svgNS" used in the getSVGElement() Method to 
> something useless or even an emty String "" the Document doesn't get 
> displayed in the JSVGCanvas during runtime at all, but if I dump the 
> file again it's correct without missing Elements, to download here:
> http://www.gup.uni-linz.ac.at/~rbrand/dump-nodisplay-nomissing.svg
> 
> So how can this happen? As the second version without displaying during 
> runtime shows all Elements are processed sucessfully, but how the heck 
> can it happen that they are not displayed in the first version?
> 
> hmmm?
> 
> Thanks for any hints!
> Reinhard




---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org