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 Michael Jurke <ju...@zedat.fu-berlin.de> on 2010/04/27 12:27:11 UTC
resizing SWT embedded JSVGCanvas
Hi,
still pending is the problem of resizing a JSVGCanvas. I attached the
code for a very simple whiteboard to draw lines.
After resizing, batik rendering get's strange behavior. Sometimes, on
smaller window, parts get rendered doubled on the downside or cheesy
background stays somehow. Sometimes rendering stucks completely although
the UpdateManager works. Making the window big again, somehow magically
repairs the rendering.
Please, help me! I tried thousends of ugly workarrounds, some do work
like changing and resetting the SVGDocument but lead to bad performance
and flickering.
System.setProperty("sun.awt.noerasebackground", "true"),
SWT.NO_REDRAW_RESIZE, SWT.NO_BACKGROUND are not connected to the problem.
Regards
Michael
Here see the attached code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.svg.AbstractJSVGComponent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;
public class SimpleWhiteboard extends Composite {
static {
System.setProperty("sun.awt.noerasebackground", "true");
}
public SimpleWhiteboard(Composite parent, int mode) {
super(parent, mode);
this.setLayout(new FillLayout());
new SimpleSVGSurface(this);
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Whiteboard");
shell.setLayout(new FillLayout());
SimpleWhiteboard instance = new SimpleWhiteboard(shell,
SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
instance.dispose();
}
public static class SimpleSVGSurface extends Composite {
private JSVGCanvas svgCanvas = null;
private Frame frame = null;
private Document svgDocument = null;
public SimpleSVGSurface(Composite parent) {
this(parent, SWT.NONE);
}
public SimpleSVGSurface(Composite parent, int mode) {
super(parent, mode | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE
| SWT.EMBEDDED);
init();
initXMLGraphics();
initListeners();
}
protected void init() {
svgCanvas = new JSVGCanvas();
svgCanvas.setDocumentState(AbstractJSVGComponent.ALWAYS_DYNAMIC);
svgCanvas.setLayout(new BorderLayout());
svgCanvas.setDoubleBuffered(true);
svgCanvas.setDoubleBufferedRendering(true);
frame = SWT_AWT.new_Frame(this);
frame.setLayout(new BorderLayout());
frame.add(BorderLayout.CENTER, svgCanvas);
frame.setEnabled(true);
frame.pack();
frame.setVisible(true);
}
protected void initXMLGraphics() {
DOMImplementation impl = SVGDOMImplementation
.getDOMImplementation();
String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
svgDocument = impl.createDocument(svgNS, "svg", null);
SVGGraphics2D svgGraphics = new SVGGraphics2D(svgDocument);
// fill the SVG Document with the Defaults
Element root = svgGraphics
.getRoot(svgDocument.getDocumentElement());
root.setAttributeNS(null, "overflow", "visible");
svgCanvas.setDocument(svgDocument);
}
private static Point lastPoint = null;
protected void initListeners() {
svgCanvas.addMouseListener(new java.awt.event.MouseListener() {
public void mouseClicked(java.awt.event.MouseEvent e) {
//
}
public void mouseEntered(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(java.awt.event.MouseEvent e) {
//
}
public void mousePressed(java.awt.event.MouseEvent e) {
System.out.print("MouseDown ");
if (lastPoint == null)
lastPoint = e.getPoint();
appendLine(lastPoint, e.getPoint());
lastPoint = e.getPoint();
}
public void mouseReleased(java.awt.event.MouseEvent e) {
//
}
});
svgCanvas
.addMouseMotionListener(new
java.awt.event.MouseMotionListener() {
public void mouseDragged(java.awt.event.MouseEvent e) {
System.out.print("MouseDragged ");
appendLine(lastPoint, e.getPoint());
lastPoint = e.getPoint();
}
public void mouseMoved(java.awt.event.MouseEvent e) {
// System.out.println("MouseMoved");
}
});
initDebugListener();
}
private void appendLine(final Point start, final Point end) {
svgCanvas.getUpdateManager().getUpdateRunnableQueue().invokeLater(
new Runnable() {
public void run() {
System.out.println("WM works");
SVGDocument doc = svgCanvas.getSVGDocument();
String SVGNS =
SVGDOMImplementation.SVG_NAMESPACE_URI;
Element g = doc.createElementNS(SVGNS, "g");
Element e = doc.createElementNS(SVGNS, "line");
e.setAttributeNS(null, "fill", "none");
e.setAttributeNS(null, "x1", String.valueOf(start
.getX()));
e.setAttributeNS(null, "y1", String.valueOf(start
.getY()));
e
.setAttributeNS(null, "x2", String.valueOf(end
.getX()));
e
.setAttributeNS(null, "y2", String.valueOf(end
.getY()));
g.appendChild(e);
doc.getRootElement().appendChild(g);
}
});
}
@Override
public void dispose() {
// should be disposed by the AWT thread to avoid deadlocks
EventQueue.invokeLater(new Runnable() {
public void run() {
svgCanvas.dispose();
frame.dispose();
}
});
super.dispose();
}
private void initDebugListener() {
svgCanvas.addComponentListener(new ComponentListener() {
public void componentHidden(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
public void componentMoved(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
public void componentResized(ComponentEvent arg0) {
System.out.println("Resize: " + svgCanvas.getSize());
}
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
});
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
Re: resizing SWT embedded JSVGCanvas
Posted by dao <da...@gmail.com>.
hello,
I have embeded a svg canvas into a composite using SWT_AWT too.
It works fine for me except for the keyboard interactors (ctrl+T and zoom in
and out does not work properly, I don't know why)
here is the code (if you have the solution for the keyboard interactors, by
the way). Note the super(parent, SWT.EMBEDDED); the MaskedSvgCanvas is just
a canvas with additional layers for selection/edition (the canvas is
ALWAYS_DYNAMIC)
/*
* Created on 09.03.2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package com.moow.svg.editor;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Panel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.w3c.dom.svg.SVGDocument;
import com.moow.svg.domain.symbol.GraphicalComponentBean;
import com.moow.svg.toolkit.ui.MaskedSvgCanvas;
import com.moow.svg.toolkit.ui.SvgComponent;
public class SVGComposite extends Composite {
private final MaskedSvgCanvas svgCanvas;
private Frame frame;
private DropTarget dropTarget;
public SVGComposite(Composite parent, int style, boolean showScrollbars,
MaskedSvgCanvas canvas) {
super(parent, SWT.EMBEDDED);
this.svgCanvas = canvas;
parent.setLayout(new FillLayout());
/*
* Set a Windows specific AWT property that prevents heavyweight
* components from erasing their background. Note that this is a global
* property and cannot be scoped. It might not be suitable for your
* application.
*/
try {
System.setProperty("sun.awt.noerasebackground", "true");
} catch (NoSuchMethodError error) {
error.printStackTrace();
}
try {
svgCanvas.setLayout(new BorderLayout());
frame = SWT_AWT.new_Frame(this);
Panel panel = new Panel(new BorderLayout())
{
public void update(java.awt.Graphics g) {
super.update(g);
/* Do not erase the background */
paint(g);
}
};
JRootPane root = new JRootPane();
panel.add(root);
java.awt.Container contentPane = root.getContentPane();
contentPane.setLayout(new BorderLayout());
if (showScrollbars) {
contentPane
.add(BorderLayout.CENTER, new JScrollPane(svgCanvas));
} else {
contentPane.add(BorderLayout.CENTER, svgCanvas);
}
frame.setLayout(new BorderLayout());
frame.add(BorderLayout.CENTER, panel);
frame.setEnabled(true);
} catch (Throwable t) {
t.printStackTrace();
}
}
public void dispose() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.dispose();
svgCanvas.dispose();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
super.dispose();
}
public SVGDocument getSVGDocument() {
SVGDocument svgDocument = svgCanvas.getSVGDocument();
if (svgDocument==null)
System.err.println("attention, on a enlevé le svgCanvas.waitIsUsable() et ca
fout la merde!!!");
return svgDocument;
}
public MaskedSvgCanvas getSvgCanvas() {
return svgCanvas;
}
public SvgComponent insertSvgComponent(int x, int y,
GraphicalComponentBean graphicalComponentBean) {
// TODO Auto-generated method stub
return null;
}
public void removeGraphicalComponent(String id) {
// TODO Auto-generated method stub
}
public void makeRegistrations(final SVGCompositeDropListener dropListener) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (dropTarget!=null)
dropTarget.dispose();
int operations = DND.DROP_COPY| DND.DROP_MOVE;
dropTarget = new DropTarget(SVGComposite.this, operations);
dropTarget.setTransfer(new Transfer[]
{LocalSelectionTransfer.getTransfer()});
dropTarget.addDropListener(dropListener);
}
});
}
public void unmakeRegistrations() {
if (dropTarget!=null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
dropTarget.dispose();
dropTarget=null;
}
});
}
}
}
On Thu, Apr 29, 2010 at 12:10 PM, <th...@kodak.com> wrote:
> Hi Michael,
>
> Michael Jurke <ju...@zedat.fu-berlin.de> wrote on 04/27/2010 11:04:34 AM:
>
>
> > I found out there are different problems when using Direct3D or openGL
> > (vm argument -Dsun.java2d.opengl=true) for rendering. Doubled rendering
> > of parts of the image appears with D3D only, with openGL I get some
> > vertical shaking when resizing (not horizontal, strange). Furthermore,
> > moving the shell doesn't update the openGL image - on move yes, but
> > after drawing a line again the image is still where it used to be before
> > the shell's position got changed (can be fixed by an extra listener).
> > It's okay for me to use openGL only, maybe anyone has an idea how to
> > correct the shaking or there might be a better solution when moving the
> > shell?
>
>
> What is "the shell"?
>
> > Finally, still the batik rendering get's stucked, so hopefully
> > anybody has an idea how can I revive it without having to use strange
> > workarounds?
>
> In the updateCompleted method it calls invokeAndWait to update the
> canvas. This is the sort of thing that given potential differences
> between Swing and SWT could lead to a dead lock.
>
>
> > About the code, going throw line by line in different threads, first I
> > found a reason for flickering:
> > AbstractJGVTComponent.paintComponent() calls g2d.fillRect with the
> > background color before painting the image. Why? Wouldn't it be much
> > better to paint on the image first - isn't this meant by double
> > buffering? It seems to be an error.
>
> The Image we draw is often mostly transparent. So we need to draw
> the background color so it can show through the transparent parts of
> the SVG image.
>
> And in any case if this causes flickering then the binding between
> swing and SWT is really badly broken. You shouldn't be able to see
> the 'intermediate' drawing results, I would think you should only see
> the drawing when it's done with the paint method.
>
> > With D3D getRenderRect() sometimes seems to return some wrong values,
> > also the image is not updated properly (results in painting the same
> > image on different locations on small windows). However, as openGL is
> > preferable for us anyway I now have to search the reason for shaking
> > vertically.
>
> I don't see these sorts of problem using just swing so the problem
> must be somewhere in the swing<->SWT translator.
>
> > On 27.04.2010 12:46, thomas.deweese@kodak.com wrote:
> > > Hi Michael,
> > >
> > > Michael Jurke<ju...@zedat.fu-berlin.de> wrote on 04/27/2010 06:27:11
> AM:
> > >
> > >
> > >> After resizing, batik rendering get's strange behavior. Sometimes, on
> > >> smaller window, parts get rendered doubled on the downside or cheesy
> > >> background stays somehow. Sometimes rendering stucks completely
> although
> > >>
> > >
> > >> the UpdateManager works. Making the window big again, somehow
> magically
> > >> repairs the rendering.
> > >>
> > > If I had to guess something goes bad in the SWT<->Swing connection
> > > on resize. My best guess would be the problem is related to our update
> > > handling. In particular you might look at JSVGComponent in particular
> > > the 'updateCompleted' method (~line 1971). I could imagine that the
> > > 'repaint' and/or paintImmediately could have problems, especially given
> > > the use of invokeAndWait.
> > >
> > > You might see if doing a simple repaint of everything avoids the
> > > issues (this would be less efficient but much more efficient than
> > > setting the whole document).
> > >
> > >
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> > For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
> >
>
>
--
Dao Hodac
Re: resizing SWT embedded JSVGCanvas
Posted by th...@kodak.com.
Hi Michael,
Michael Jurke <ju...@zedat.fu-berlin.de> wrote on 04/27/2010 11:04:34 AM:
> I found out there are different problems when using Direct3D or openGL
> (vm argument -Dsun.java2d.opengl=true) for rendering. Doubled rendering
> of parts of the image appears with D3D only, with openGL I get some
> vertical shaking when resizing (not horizontal, strange). Furthermore,
> moving the shell doesn't update the openGL image - on move yes, but
> after drawing a line again the image is still where it used to be before
> the shell's position got changed (can be fixed by an extra listener).
> It's okay for me to use openGL only, maybe anyone has an idea how to
> correct the shaking or there might be a better solution when moving the
> shell?
What is "the shell"?
> Finally, still the batik rendering get's stucked, so hopefully
> anybody has an idea how can I revive it without having to use strange
> workarounds?
In the updateCompleted method it calls invokeAndWait to update the
canvas. This is the sort of thing that given potential differences
between Swing and SWT could lead to a dead lock.
> About the code, going throw line by line in different threads, first I
> found a reason for flickering:
> AbstractJGVTComponent.paintComponent() calls g2d.fillRect with the
> background color before painting the image. Why? Wouldn't it be much
> better to paint on the image first - isn't this meant by double
> buffering? It seems to be an error.
The Image we draw is often mostly transparent. So we need to draw
the background color so it can show through the transparent parts of
the SVG image.
And in any case if this causes flickering then the binding between
swing and SWT is really badly broken. You shouldn't be able to see
the 'intermediate' drawing results, I would think you should only see
the drawing when it's done with the paint method.
> With D3D getRenderRect() sometimes seems to return some wrong values,
> also the image is not updated properly (results in painting the same
> image on different locations on small windows). However, as openGL is
> preferable for us anyway I now have to search the reason for shaking
> vertically.
I don't see these sorts of problem using just swing so the problem
must be somewhere in the swing<->SWT translator.
> On 27.04.2010 12:46, thomas.deweese@kodak.com wrote:
> > Hi Michael,
> >
> > Michael Jurke<ju...@zedat.fu-berlin.de> wrote on 04/27/2010 06:27:11
AM:
> >
> >
> >> After resizing, batik rendering get's strange behavior. Sometimes, on
> >> smaller window, parts get rendered doubled on the downside or cheesy
> >> background stays somehow. Sometimes rendering stucks completely
although
> >>
> >
> >> the UpdateManager works. Making the window big again, somehow
magically
> >> repairs the rendering.
> >>
> > If I had to guess something goes bad in the SWT<->Swing connection
> > on resize. My best guess would be the problem is related to our
update
> > handling. In particular you might look at JSVGComponent in particular
> > the 'updateCompleted' method (~line 1971). I could imagine that the
> > 'repaint' and/or paintImmediately could have problems, especially
given
> > the use of invokeAndWait.
> >
> > You might see if doing a simple repaint of everything avoids the
> > issues (this would be less efficient but much more efficient than
> > setting the whole document).
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
>
Re: resizing SWT embedded JSVGCanvas
Posted by Michael Jurke <ju...@zedat.fu-berlin.de>.
Hi again,
I found out there are different problems when using Direct3D or openGL
(vm argument -Dsun.java2d.opengl=true) for rendering. Doubled rendering
of parts of the image appears with D3D only, with openGL I get some
vertical shaking when resizing (not horizontal, strange). Furthermore,
moving the shell doesn't update the openGL image - on move yes, but
after drawing a line again the image is still where it used to be before
the shell's position got changed (can be fixed by an extra listener).
It's okay for me to use openGL only, maybe anyone has an idea how to
correct the shaking or there might be a better solution when moving the
shell? Finally, still the batik rendering get's stucked, so hopefully
anybody has an idea how can I revive it without having to use strange
workarounds?
Or already a solution for me - if anybody has an idea - where how to
know whether rendering got stucked, it would be very, very great!!! So I
could check and call setDocument only when there is a problem.
About the code, going throw line by line in different threads, first I
found a reason for flickering:
AbstractJGVTComponent.paintComponent() calls g2d.fillRect with the
background color before painting the image. Why? Wouldn't it be much
better to paint on the image first - isn't this meant by double
buffering? It seems to be an error.
With D3D getRenderRect() sometimes seems to return some wrong values,
also the image is not updated properly (results in painting the same
image on different locations on small windows). However, as openGL is
preferable for us anyway I now have to search the reason for shaking
vertically.
Thanks a lot for any help!
Regards
Michael
On 27.04.2010 12:46, thomas.deweese@kodak.com wrote:
> Hi Michael,
>
> Michael Jurke<ju...@zedat.fu-berlin.de> wrote on 04/27/2010 06:27:11 AM:
>
>
>> After resizing, batik rendering get's strange behavior. Sometimes, on
>> smaller window, parts get rendered doubled on the downside or cheesy
>> background stays somehow. Sometimes rendering stucks completely although
>>
>
>> the UpdateManager works. Making the window big again, somehow magically
>> repairs the rendering.
>>
> If I had to guess something goes bad in the SWT<->Swing connection
> on resize. My best guess would be the problem is related to our update
> handling. In particular you might look at JSVGComponent in particular
> the 'updateCompleted' method (~line 1971). I could imagine that the
> 'repaint' and/or paintImmediately could have problems, especially given
> the use of invokeAndWait.
>
> You might see if doing a simple repaint of everything avoids the
> issues (this would be less efficient but much more efficient than
> setting the whole document).
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
Re: resizing SWT embedded JSVGCanvas
Posted by Michael Jurke <ju...@zedat.fu-berlin.de>.
On 27.04.2010 12:46, thomas.deweese@kodak.com wrote:
> Hi Michael,
>
> Michael Jurke<ju...@zedat.fu-berlin.de> wrote on 04/27/2010 06:27:11 AM:
>
>
>> After resizing, batik rendering get's strange behavior. Sometimes, on smaller window, parts get rendered doubled on the downside or cheesy background stays somehow. Sometimes rendering stucks completely although the UpdateManager works. Making the window big again, somehow magically repairs the rendering.
>>
> If I had to guess something goes bad in the SWT<->Swing connection
> on resize. My best guess would be the problem is related to our update
> handling. In particular you might look at JSVGComponent in particular
> the 'updateCompleted' method (~line 1971). I could imagine that the
> 'repaint' and/or paintImmediately could have problems, especially given
> the use of invokeAndWait.
>
Ok, I try to search for it.
> You might see if doing a simple repaint of everything avoids the
> issues (this would be less efficient but much more efficient than
> setting the whole document).
>
Unfortunately repaint doesn't help. Actually the behavior is little
deterministic. In some composite constallations the problem of wrong
rendering of some parts somewhere gets solved, but still batik dynamic
rendering gets stucked.
So if anyone has an idea just how to revive it, would be great and solve
my main problem! What worked out for example was to set deactivate the
layout manager, set the JSVGCanvas size to 0 and back, reactivate and to
call repaint or to change and set the document again. ;)
Regards,
Michael
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
Re: resizing SWT embedded JSVGCanvas
Posted by th...@kodak.com.
Hi Michael,
Michael Jurke <ju...@zedat.fu-berlin.de> wrote on 04/27/2010 06:27:11 AM:
> After resizing, batik rendering get's strange behavior. Sometimes, on
> smaller window, parts get rendered doubled on the downside or cheesy
> background stays somehow. Sometimes rendering stucks completely although
> the UpdateManager works. Making the window big again, somehow magically
> repairs the rendering.
If I had to guess something goes bad in the SWT<->Swing connection
on resize. My best guess would be the problem is related to our update
handling. In particular you might look at JSVGComponent in particular
the 'updateCompleted' method (~line 1971). I could imagine that the
'repaint' and/or paintImmediately could have problems, especially given
the use of invokeAndWait.
You might see if doing a simple repaint of everything avoids the
issues (this would be less efficient but much more efficient than
setting the whole document).