-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

hello thomas!

maybe its useful if i post my code (i dont think its too much), maybe im
doing something wrong, since im not so experienced with batik. the
flickering appears very little when i run the program "standalone"
meaing only a swt frame with my joystick in it. if i integrate it in our
big application (which uses full screen swt on multiple displays) the
flickering gets very internse and somethime the whole svg disappears.
the application is desgined to be a "joystick" to control a hardware
component. maybe someone of you could have a look at the code and see if
i did something wrong when doing the element updates (in methods
moveCircle() and reset()).

thanks,
marc

[EMAIL PROTECTED] wrote:
> Hi Marc,
> 
> I ment to also say, that if the SWT folks can identify something wrong or
> odd that we are doing that causes the problem, I'd be interested in
> hearing about it.
> 
> If it's something simple to fix or wouldn't impact normal usage of Batik
> (or can be put
> in a special subclass etc) it would be nice to have Batik work cleanly
> in SWT.
> 
> Thomas E. DeWeese/449433/EKC wrote on 06/02/2007 08:26:23 AM:
> 
>> Hi Marc,
>>
>> Marc Doerflinger <[EMAIL PROTECTED]> wrote on
>> 05/30/2007 09:47:21 AM:
>>
>> > im using a JSVGCanvas embedded inside a SWT Container. the jsvgcanvas
>> > state is set to ALWAYS_DYNAMIC  since i update some svg components via
>> > dom to move them around in the picture. when i move them fast (input via
>> > mouselisteners), im getting bad flickering in the svgcanvs around the
>> > moved object, also sometimes the update just stops and the picture
>> > update seems to hang. im using jdk 1.6.01 and 1.5.11.
>> > enabling double buffering does not help at all, the result is unchanged.
>> > what else could i do to improve the performance?
> 
>>    Stop using SWT?  Since this never happens with Swing/AWT I suspect it's
>> an issue with how SWT supports Swing.  Unfortunately I don't know anything
>> about SWT so I can't help much.
> 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGY8Vk6mRZxtk0FrcRAtSWAJwNEtd6+7yVU9QSdd+tFjEdq2EX6ACfbI9l
I6O8rs72lgy+DjgG7JWUbeU=
=JYmb
-----END PGP SIGNATURE-----
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import org.apache.batik.dom.events.DOMMouseEvent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.svggen.SVGSyntax;
import org.apache.batik.swing.JSVGCanvas;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Element;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.svg.SVGDocument;

public class VirtualJoystick extends JSVGCanvas {

        // private Logger _logger = Logger.getLogger(VirtualJoystick.class);

        /** height of the widget */
        private int _height;

        /** width of the widget */
        private int _width;

        private SVGDocument _document;

        /** the space between the gradientcircle and the border of the widget */
        private int _border;

        /** the link to the small circle element in the xml */
        private Element _circle;

        /** the y coord of the center */
        private int _midY;

        /** the x coord of the center */
        private int _midX;

        /** the radius of the gradient circle */
        private int _gradientRadius;

        /** true if the mousebutton is currenty down */
        private boolean _mouseButtonPressed = false;

        /** the radius of the inner circle (steering ball) */
        private int _ballRadius;

        /** the background color of the recangle around the circles */
        private String _bgcolor;

        /** true if the mouse if outside the svg widget */
        private boolean _mouseOutOfSvg = false;

        /**
         * the dx or dy of the cursor has to change by this value otherweise 
there
         * is no movement motification sent to the listener
         */
        private int _threshold;

        /**
         * the x coord of the position where the listener was last notified of a
         * movement change
         */
        private long _lastNotifiedX;

        /**
         * the y coord of the position where the listener was last notified of a
         * movement change
         */
        private long _lastNotifiedY;

        /** the listener, thats waits for notifications about joystick movement 
*/
        private IVirtualJoystickListener _joystickListener;

        /** the xml element for the gradient of the outer circle */
        private Element _outercircleGradient;

        /** the xml element of the outer circle */
        private Element _gradientCircle;

        /** the line style for the crosshair in the outer circle */
        private String _arrowStyle;

        private DOMImplementation _impl;

        public VirtualJoystick(int width, int height, int border, String 
ballStyle,
                        int ballRadius, String gradientInnerColor,
                        String gradientOuterColor, String backgroundColor, int 
threshold,
                        IVirtualJoystickListener listener, String arrowStyle) {
                super();
                
                _height = height;
                _width = width;
                _border = border;
                _midX = Math.round(_width / 2);
                _midY = Math.round(_height / 2);
                if (_height < _width) {
                        _gradientRadius = Math.round((_height - 2 * _border) / 
2);
                } else {
                        _gradientRadius = Math.round((_width - 2 * _border) / 
2);
                }
                _ballRadius = ballRadius;
                _bgcolor = backgroundColor;
                _threshold = threshold;
                _joystickListener = listener;
                _arrowStyle = arrowStyle;

                _impl = SVGDOMImplementation.getDOMImplementation();
                String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
                _document = (SVGDocument) _impl.createDocument(svgNS, "svg", 
null);
                
                setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);

                Element root = _document.getDocumentElement();
                root.setAttributeNS(null, "width", Integer.toString(_width));
                root.setAttributeNS(null, "height", Integer.toString(_height));

                //setSize(new Dimension(_width, _height));

                createBackground(svgNS, root);

                createControlArea(gradientInnerColor, gradientOuterColor, 
svgNS, root);

                createController(ballStyle, ballRadius, svgNS, root);

                setSVGDocument(_document);

                setupMouseEventsOutsideSVG();
        }

        private void setupMouseEventsOutsideSVG() {
                addMouseListener(new MouseAdapter() {
                        @Override
                        public void mouseExited(MouseEvent e) {
                                _mouseOutOfSvg = true;
                        }

                        @Override
                        public void mouseEntered(MouseEvent e) {
                                _mouseOutOfSvg = false;
                        }

                        @Override
                        public void mouseReleased(MouseEvent e) {
                                resetCircle();
                        }
                });

                addMouseMotionListener(new MouseMotionAdapter() {
                        @Override
                        public void mouseDragged(MouseEvent e) {
                                if (_mouseOutOfSvg) {
                                        moveCircle(e.getPoint().x, 
e.getPoint().y);
                                }
                        }
                });
        }

        private void createController(String ballStyle, int ballRadius,
                        String svgNS, Element root) {
                _circle = _document.createElementNS(svgNS, 
SVGSyntax.SVG_CIRCLE_TAG);
                _circle.setAttributeNS(null, "cx", Integer.toString(_midX));
                _circle.setAttributeNS(null, "cy", Integer.toString(_midY));
                _circle.setAttributeNS(null, "r", Integer.toString(ballRadius));
                _circle.setAttributeNS(null, "style", ballStyle);

                ((EventTarget) _circle).addEventListener("mousemove",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                DOMMouseEvent mevt = 
(DOMMouseEvent) evt;
                                                moveCircle(mevt.getClientX(), 
mevt.getClientY());
                                        }
                                }, false);

                ((EventTarget) _circle).addEventListener("mousedown",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                _mouseButtonPressed = true;
                                                _mouseOutOfSvg = false;
                                                _lastNotifiedX = 0;
                                                _lastNotifiedY = 0;
                                        }
                                }, false);

                ((EventTarget) _circle).addEventListener("mouseup",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                // _logger.debug("Mousebutton 
up");
                                                resetCircle();
                                        }
                                }, false);

                ((EventTarget) _circle).addEventListener("mouseout",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                DOMMouseEvent mevt = 
(DOMMouseEvent) evt;
                                                if (_mouseButtonPressed) {
                                                        
moveCircle(mevt.getClientX(), mevt.getClientY());
                                                } else {
                                                        resetCircle();
                                                }
                                        }
                                }, false);

                root.appendChild(_circle);
        }

        private void createControlArea(String gradientInnerColor,
                        String gradientOuterColor, String svgNS, Element root) {
                _outercircleGradient = _document.createElementNS(svgNS,
                                SVGSyntax.SVG_RADIAL_GRADIENT_TAG);
                _outercircleGradient.setAttributeNS(null, "id", "radial1");
                _outercircleGradient.setAttributeNS(null, "cx", "0.5");
                _outercircleGradient.setAttributeNS(null, "cy", "0.5");
                root.appendChild(_outercircleGradient);

                Element stop = _document.createElementNS(svgNS, 
SVGSyntax.SVG_STOP_TAG);
                stop.setAttributeNS(null, "stop-color", gradientInnerColor);
                stop.setAttributeNS(null, "offset", "0%");
                _outercircleGradient.appendChild(stop);

                stop = _document.createElementNS(svgNS, SVGSyntax.SVG_STOP_TAG);
                stop.setAttributeNS(null, "stop-color", gradientOuterColor);
                stop.setAttributeNS(null, "offset", "100%");
                _outercircleGradient.appendChild(stop);

                createArrows(svgNS, root);

                _gradientCircle = _document.createElementNS(svgNS,
                                SVGSyntax.SVG_CIRCLE_TAG);
                _gradientCircle.setAttributeNS(null, "cx", 
Integer.toString(_midX));
                _gradientCircle.setAttributeNS(null, "cy", 
Integer.toString(_midY));
                _gradientCircle.setAttributeNS(null, "r", Integer
                                .toString(_gradientRadius));
                _gradientCircle.setAttributeNS(null, "style",
                                "stroke:black;stroke-width:1;fill-opacity:0.8");
                _gradientCircle.setAttributeNS(null, "fill", "url(#radial1)");

                ((EventTarget) _gradientCircle).addEventListener("mousemove",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                DOMMouseEvent mevt = 
(DOMMouseEvent) evt;
                                                moveCircle(mevt.getClientX(), 
mevt.getClientY());
                                        }
                                }, false);

                ((EventTarget) _gradientCircle).addEventListener("mousedown",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                _mouseButtonPressed = true;
                                                _mouseOutOfSvg = false;
                                                _lastNotifiedX = 0;
                                                _lastNotifiedY = 0;
                                                DOMMouseEvent mevt = 
(DOMMouseEvent) evt;
                                                moveCircle(mevt.getClientX(), 
mevt.getClientY());
                                        }
                                }, false);

                ((EventTarget) _gradientCircle).addEventListener("mouseup",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                resetCircle();
                                        }
                                }, false);

                root.appendChild(_gradientCircle);
        }

        private void createArrows(String svgNS, Element root) {
                long distMidToTriangle = Math.round(_gradientRadius / 2);
                long triangleHeight = Math.round(_gradientRadius / 3);

                Element arrow = _document.createElementNS(svgNS,
                                SVGSyntax.SVG_POLYGON_TAG);
                arrow.setAttributeNS(null, SVGSyntax.SVG_STYLE_ATTRIBUTE, 
_arrowStyle);
                String points = Long.toString(_midX + distMidToTriangle) + ","
                                + Long.toString(_midY - triangleHeight) + " ";
                points += Long.toString(_midX + distMidToTriangle + 
triangleHeight)
                                + "," + Long.toString(_midY) + " ";
                points += Long.toString(_midX + distMidToTriangle) + ","
                                + Long.toString(_midY + triangleHeight);
                arrow.setAttributeNS(null, SVGSyntax.SVG_POINTS_ATTRIBUTE, 
points);
                root.appendChild(arrow);

                arrow = _document.createElementNS(svgNS, 
SVGSyntax.SVG_POLYGON_TAG);
                arrow.setAttributeNS(null, SVGSyntax.SVG_STYLE_ATTRIBUTE, 
_arrowStyle);
                points = Long.toString(_midX + triangleHeight) + ","
                                + Long.toString(_midY - distMidToTriangle) + " 
";
                points += Long.toString(_midX) + ","
                                + Long.toString(_midY - distMidToTriangle - 
triangleHeight)
                                + " ";
                points += Long.toString(_midX - triangleHeight) + ","
                                + Long.toString(_midY - distMidToTriangle);
                arrow.setAttributeNS(null, SVGSyntax.SVG_POINTS_ATTRIBUTE, 
points);
                root.appendChild(arrow);

                arrow = _document.createElementNS(svgNS, 
SVGSyntax.SVG_POLYGON_TAG);
                arrow.setAttributeNS(null, SVGSyntax.SVG_STYLE_ATTRIBUTE, 
_arrowStyle);
                points = Long.toString(_midX + triangleHeight) + ","
                                + Long.toString(_midY + distMidToTriangle) + " 
";
                points += Long.toString(_midX) + ","
                                + Long.toString(_midY + distMidToTriangle + 
triangleHeight)
                                + " ";
                points += Long.toString(_midX - triangleHeight) + ","
                                + Long.toString(_midY + distMidToTriangle);
                arrow.setAttributeNS(null, SVGSyntax.SVG_POINTS_ATTRIBUTE, 
points);
                root.appendChild(arrow);

                arrow = _document.createElementNS(svgNS, 
SVGSyntax.SVG_POLYGON_TAG);
                arrow.setAttributeNS(null, SVGSyntax.SVG_STYLE_ATTRIBUTE, 
_arrowStyle);
                points = Long.toString(_midX - distMidToTriangle) + ","
                                + Long.toString(_midY - triangleHeight) + " ";
                points += Long.toString(_midX - distMidToTriangle - 
triangleHeight)
                                + "," + Long.toString(_midY) + " ";
                points += Long.toString(_midX - distMidToTriangle) + ","
                                + Long.toString(_midY + triangleHeight);
                arrow.setAttributeNS(null, SVGSyntax.SVG_POINTS_ATTRIBUTE, 
points);
                root.appendChild(arrow);
        }

        private void createBackground(String svgNS, Element root) {
                Element background = _document.createElementNS(svgNS,
                                SVGSyntax.SVG_RECT_TAG);
                background.setAttributeNS(null, "x", "0");
                background.setAttributeNS(null, "width", 
Integer.toString(_width));
                background.setAttributeNS(null, "y", "0");
                background
                                .setAttributeNS(null, "height", 
Integer.toString(_height));
                background.setAttributeNS(null, "style", 
"stroke:black;stroke-width:0");
                background.setAttributeNS(null, "fill", _bgcolor);

                ((EventTarget) background).addEventListener("mousemove",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                if (_mouseButtonPressed) {
                                                        DOMMouseEvent mevt = 
(DOMMouseEvent) evt;
                                                        
moveCircle(mevt.getClientX(), mevt.getClientY());
                                                }
                                        }
                                }, false);

                ((EventTarget) background).addEventListener("mouseup",
                                new EventListener() {
                                        public void handleEvent(Event evt) {
                                                if (_mouseButtonPressed) {
                                                        _mouseButtonPressed = 
false;
                                                        resetCircle();
                                                }
                                        }
                                }, false);

                root.appendChild(background);
        }

        public void moveCircle(int mouseX, int mouseY) {
                if (_mouseButtonPressed) {
                        int dx = mouseX - _midX;
                        int dy = mouseY - _midY;
                        double distToCenter = Math.round(Math.sqrt(Math.pow(dx, 
2)
                                        + Math.pow(dy, 2)));
                        if (distToCenter < _gradientRadius - _ballRadius) {
                                moveCircleElement(mouseX, mouseY);

                                notifyListener(dx, dy);
                        } else /* if (distToCenter < _gradientRadius) */{
                                // the radius where the sphere will be shown
                                int endRadius = _gradientRadius - _ballRadius;

                                // the x and y offset of the mouse cursor from 
the center
                                int rx = mouseX - _midX;
                                int ry = mouseY - _midY;

                                // the new x and y offsets of the sphere
                                long vx = Math.round(endRadius / distToCenter * 
rx);
                                long vy = Math.round(endRadius / distToCenter * 
ry);

                                moveCircleElement(vx + _midX, vy + _midY);

                                notifyListener(vx, vy);
                        }
                }
        }

        private void notifyListener(long dx, long dy) {
                if ((Math.abs(_lastNotifiedX - dx) > _threshold)
                                || (Math.abs(_lastNotifiedY - dy) > 
_threshold)) {
                        double pctX = dx / (double) (_gradientRadius - 
_ballRadius);
                        double pctY = -dy / (double) (_gradientRadius - 
_ballRadius);
                        _joystickListener.move(pctX, pctY);
                        _lastNotifiedX = dx;
                        _lastNotifiedY = dy;
                }
        }

        private void moveCircleElement(long mouseX, long mouseY) {
                _circle.setAttributeNS(null, "cx", Long.toString(mouseX));
                _circle.setAttributeNS(null, "cy", Long.toString(mouseY));
        }

        public void resetCircle() {
                _mouseButtonPressed = false;
                _circle.setAttributeNS(null, "cx", Integer.toString(_midX));
                _circle.setAttributeNS(null, "cy", Integer.toString(_midY));

                _joystickListener.move(0, 0);
                _lastNotifiedX = 0;
                _lastNotifiedY = 0;
        }

        public void handleZoom(double z) {
                _joystickListener.zoom(z);
        }
        
        @Override
        public void dispose() {
                _impl = null;
        }

}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to