Hi,
I know you are all probabley sick of questions about jsvgcanvas's not updating when new elements are being added to the DOM dynamically but I searched the list and consulted the FAQs and did everything I was supposed to do including calling the update manager in the GVTrenderingCompleted listener and setting the document state to always dynamic but my DOM still won't update.
So here's my problem:
I am developing an svg editor using batik and java (for personal use).
The current prototype of the editor allows you to create a new svg file
or open an existing svg file (no problems there).
I know you are all probabley sick of questions about jsvgcanvas's not updating when new elements are being added to the DOM dynamically but I searched the list and consulted the FAQs and did everything I was supposed to do including calling the update manager in the GVTrenderingCompleted listener and setting the document state to always dynamic but my DOM still won't update.
So here's my problem:
I am developing an svg editor using batik and java (for personal use).
The current prototype of the editor allows you to create a new svg file
or open an existing svg file (no problems there).
In the case of an exisiting SVG file it gets the DOM tree using SAXSVGDocumentFactory and createDocument.
The GUI contains a DOMViewer.Panel which displays the elements in the DOMTree of the current document (really useful btw:0))
Once you open a file it allows you to create a new oval or rectangle element. You do this like you create a new shape in any drawing programme, You click the relevant button and drag the mouse over the canvas to draw the shape. In my programme as the user drags the mouse the shape is drawn in java.awt.graphics.When the user lets go of the mouse the java.awt.graphics shape dissappears and the new
SVG element is aphended to the DOM tree.
The GUI contains a DOMViewer.Panel which displays the elements in the DOMTree of the current document (really useful btw:0))
Once you open a file it allows you to create a new oval or rectangle element. You do this like you create a new shape in any drawing programme, You click the relevant button and drag the mouse over the canvas to draw the shape. In my programme as the user drags the mouse the shape is drawn in java.awt.graphics.When the user lets go of the mouse the java.awt.graphics shape dissappears and the new
SVG element is aphended to the DOM tree.
The jsvgcanvas should then update to show the updated document with the new shape.
This is the problem, The display doesn't update - It does not show the new shape but instead the document like it was before the new shape was added.
I know that the shape is being added to the DOM because the DOM viewer shows it and if I save the file and open it again the document displays the new shape.
Naturally repaint() and refresh() and setDocument() doesn't work and anyway I read in the archives that the updatemanager should automatically refresh the document.
I added an UpdateManagerEvent listener to the canvas to get a better insight into the problem and I realised that while managerStarted and ManagerStopped are being called each time I apphend a new element to the DOM tree, Update Started and Update completed are only being called at the start when the document is loaded.
I know that the shape is being added to the DOM because the DOM viewer shows it and if I save the file and open it again the document displays the new shape.
Naturally repaint() and refresh() and setDocument() doesn't work and anyway I read in the archives that the updatemanager should automatically refresh the document.
I added an UpdateManagerEvent listener to the canvas to get a better insight into the problem and I realised that while managerStarted and ManagerStopped are being called each time I apphend a new element to the DOM tree, Update Started and Update completed are only being called at the start when the document is loaded.
I know that this is probabley why my DOM is not updating but I don't know how to fix it as I have only being using Batik for 3 weeks:0).
I don't touch the GVT tree at all as I read in a presentation someone posted in the archives (which was really good btw) that updating the DOM tree automatically updates the GVT tree in the background. (i think unless I got things horribly wrong)
I don't touch the GVT tree at all as I read in a presentation someone posted in the archives (which was really good btw) that updating the DOM tree automatically updates the GVT tree in the background. (i think unless I got things horribly wrong)
I would really appreciate if someone could let me know where I am going wrong and explain to me how to fix it.
Here is a sample of my code to create the SVG file and the runnable queue. Sorry about the lack of get and set methods.
BTW I am using j2sdk 1.4.0_02 and batik 1.5
Thanks a lot
Ciara
Thanks a lot
Ciara
public class GraphicsFile implements MouseListener, MouseMotionListener, UpdateManagerListener
{
boolean update = false;
int width; // width of svg file
int height; // height of svg file
String svgNS;
SVGDocument doc;
JSVGCanvas jsvgcanvas;
Element rootelement;
File file;
Writer out;
int x; // the x coordinate of the first mouse click on screen
int y; // the y coordinate of the first mouse click on screen
int x2; // current x of mouse
int y2; // current x of mouse
int w; // x-x2 (width of shape or selection being made)
int h; // x-x2 (width of shape or selection being made)
JScrollPane canvasPane;
Shape s =null;
GraphicsFile(int w, int h, GUI graphicaluserinterface, File afile)
{
width = w;
height = h;
//add to canvas and set GUI (the frame the canvas is displayed in
jsvgcanvas= new JSVGCanvas();
jsvgcanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
svgNS = "SVGDOMImplementation.SVG_NAMESPACE_URI";
jsvgcanvas.addMouseListener(this);
jsvgcanvas.addMouseMotionListener(this);
canvasPane = new JScrollPane(jsvgcanvas);
JPanel p = new JPanel();
p.add(canvasPane,new FlowLayout(FlowLayout.LEFT));
gui.add(p);
jsvgcanvas.addUpdateManagerListener(this);
gui.pack();
openFile(afile);
}
void openFile(File afile)
{
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
File formerfile = file;
SVGDocument formerdoc= doc;
if (file.exists())
{
try
{
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
doc = (SVGDocument)f.createDocument(file.toURL().toString());
rootelement = doc.getRootElement();
w = Integer.parseInt(rootelement.getAttribute("width"));
h = Integer.parseInt(rootelement.getAttribute("height"));
canvasPane.setPreferredSize(new Dimension(w, h));
jsvgcanvas.setSVGDocument(doc);
}
catch(Exception e)
{
}
}
//set the DOMViewer Panel to current document
gui.invalidate();
gui.validate();
// I have to invalidate and validate the GUI frame to get it to display
//updated DOMViewerPanel
jsvgcanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter()
{
public void documentLoadingCompleted(SVGDocumentLoaderEvent evt)
{
doc = jsvgcanvas.getSVGDocument();
}
});
jsvgcanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter()
{
public void gvtRenderingCompleted(GVTTreeRendererEvent e)
{
loadThread();
// the update manager thread
}
});
}
public void mousePressed(MouseEvent f)
{
x=f.getX();
y=f.getY();
w=0;
h=0;
}
public void mouseDragged(MouseEvent f)
{
// calculate coordinates and diamensions of shape
//draw the shape in java.awt.graphics2D
}
public void mouseReleased(MouseEvent f)
{
update=true;
loadThread();
//load thread calls update manager
}
public void loadThread()
{
jsvgcanvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(new Runnable()
{
public void run()
{
if(update==true)
{
// calls add SVG method on shape object see below for method
s.addSVG();
update=false;
jsvgcanvas.setDocument(doc);
gui.properties.viewtree.setDocument(doc);
gui.getContentPane().invalidate();
gui.getContentPane().validate();
// need to be called to update GUI to show changes
}
}
});
}
// implemented for debugging purposes only
public void managerStarted(UpdateManagerEvent e)
{
System.out.println("Manager Started");
}
public void managerSuspended(UpdateManagerEvent e)
{
System.out.println("Manager Suspended");
}
public void managerResumed(UpdateManagerEvent e)
{
System.out.println("Manager Resumed");
}
public void managerStopped(UpdateManagerEvent e)
{
System.out.println("Manager Stopped");
}
{
boolean update = false;
int width; // width of svg file
int height; // height of svg file
String svgNS;
SVGDocument doc;
JSVGCanvas jsvgcanvas;
Element rootelement;
File file;
Writer out;
int x; // the x coordinate of the first mouse click on screen
int y; // the y coordinate of the first mouse click on screen
int x2; // current x of mouse
int y2; // current x of mouse
int w; // x-x2 (width of shape or selection being made)
int h; // x-x2 (width of shape or selection being made)
JScrollPane canvasPane;
Shape s =null;
GraphicsFile(int w, int h, GUI graphicaluserinterface, File afile)
{
width = w;
height = h;
//add to canvas and set GUI (the frame the canvas is displayed in
jsvgcanvas= new JSVGCanvas();
jsvgcanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);
svgNS = "SVGDOMImplementation.SVG_NAMESPACE_URI";
jsvgcanvas.addMouseListener(this);
jsvgcanvas.addMouseMotionListener(this);
canvasPane = new JScrollPane(jsvgcanvas);
JPanel p = new JPanel();
p.add(canvasPane,new FlowLayout(FlowLayout.LEFT));
gui.add(p);
jsvgcanvas.addUpdateManagerListener(this);
gui.pack();
openFile(afile);
}
void openFile(File afile)
{
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
File formerfile = file;
SVGDocument formerdoc= doc;
if (file.exists())
{
try
{
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
doc = (SVGDocument)f.createDocument(file.toURL().toString());
rootelement = doc.getRootElement();
w = Integer.parseInt(rootelement.getAttribute("width"));
h = Integer.parseInt(rootelement.getAttribute("height"));
canvasPane.setPreferredSize(new Dimension(w, h));
jsvgcanvas.setSVGDocument(doc);
}
catch(Exception e)
{
}
}
//set the DOMViewer Panel to current document
gui.invalidate();
gui.validate();
// I have to invalidate and validate the GUI frame to get it to display
//updated DOMViewerPanel
jsvgcanvas.addSVGDocumentLoaderListener(new SVGDocumentLoaderAdapter()
{
public void documentLoadingCompleted(SVGDocumentLoaderEvent evt)
{
doc = jsvgcanvas.getSVGDocument();
}
});
jsvgcanvas.addGVTTreeRendererListener(new GVTTreeRendererAdapter()
{
public void gvtRenderingCompleted(GVTTreeRendererEvent e)
{
loadThread();
// the update manager thread
}
});
}
public void mousePressed(MouseEvent f)
{
x=f.getX();
y=f.getY();
w=0;
h=0;
}
public void mouseDragged(MouseEvent f)
{
// calculate coordinates and diamensions of shape
//draw the shape in java.awt.graphics2D
}
public void mouseReleased(MouseEvent f)
{
update=true;
loadThread();
//load thread calls update manager
}
public void loadThread()
{
jsvgcanvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(new Runnable()
{
public void run()
{
if(update==true)
{
// calls add SVG method on shape object see below for method
s.addSVG();
update=false;
jsvgcanvas.setDocument(doc);
gui.properties.viewtree.setDocument(doc);
gui.getContentPane().invalidate();
gui.getContentPane().validate();
// need to be called to update GUI to show changes
}
}
});
}
// implemented for debugging purposes only
public void managerStarted(UpdateManagerEvent e)
{
System.out.println("Manager Started");
}
public void managerSuspended(UpdateManagerEvent e)
{
System.out.println("Manager Suspended");
}
public void managerResumed(UpdateManagerEvent e)
{
System.out.println("Manager Resumed");
}
public void managerStopped(UpdateManagerEvent e)
{
System.out.println("Manager Stopped");
}
public void updateStarted(UpdateManagerEvent e)
{
System.out.println("Update Started");
}
{
System.out.println("Update Started");
}
public void updateCompleted(final UpdateManagerEvent e)
{
System.out.println("Update Completed");
}
public void updateFailed(UpdateManagerEvent e)
{
System.out.println("Update Failed");
}
}
///////////////////////////////////////////////////////////
addSvg method from shape object btw shape object is not a thread.
public void addSVG()
{
{
System.out.println("Update Completed");
}
public void updateFailed(UpdateManagerEvent e)
{
System.out.println("Update Failed");
}
}
///////////////////////////////////////////////////////////
addSvg method from shape object btw shape object is not a thread.
public void addSVG()
{
String sx = String.valueOf(x);
String sy = String.valueOf(y);
String sw = String.valueOf(w);
String sh = String.valueOf(h);
Element e = svgfile.doc.createElementNS(svgfile.svgNS, "rect");
e.setAttribute( "x",sx);
e.setAttribute("y",sy );
e.setAttribute("width",sw );
e.setAttribute("height",sh );
e.setAttribute(
"style",
"stroke:"
+"RGB("+Integer.toString(strokecolor.getRed())+", "
+Integer.toString(strokecolor.getGreen())+", "
+Integer.toString(strokecolor.getBlue())+")"
);
//strokecolor is my color object retruned from my Jcolor chooser
//as is fill color
e.setAttribute(
"style",
"fill:"
+"RGB("+Integer.toString(fillcolor.getRed())+", "
+Integer.toString(fillcolor.getGreen())+", "
+Integer.toString(fillcolor.getBlue())+")"
);
// sorry about the lack of get and set methods I know it's bad programming
//practise
svgfile.doc.getRootElement().appendChild(e);
System.out.println("rect");
String sy = String.valueOf(y);
String sw = String.valueOf(w);
String sh = String.valueOf(h);
Element e = svgfile.doc.createElementNS(svgfile.svgNS, "rect");
e.setAttribute( "x",sx);
e.setAttribute("y",sy );
e.setAttribute("width",sw );
e.setAttribute("height",sh );
e.setAttribute(
"style",
"stroke:"
+"RGB("+Integer.toString(strokecolor.getRed())+", "
+Integer.toString(strokecolor.getGreen())+", "
+Integer.toString(strokecolor.getBlue())+")"
);
//strokecolor is my color object retruned from my Jcolor chooser
//as is fill color
e.setAttribute(
"style",
"fill:"
+"RGB("+Integer.toString(fillcolor.getRed())+", "
+Integer.toString(fillcolor.getGreen())+", "
+Integer.toString(fillcolor.getBlue())+")"
);
// sorry about the lack of get and set methods I know it's bad programming
//practise
svgfile.doc.getRootElement().appendChild(e);
System.out.println("rect");
BT Yahoo! Broadband - Free modem offer, sign up online today and save �80
