with your help, i can draw flicker free.. thanks.. but now i am after the
efficiency.. i am currently trying the glass pane and i am having a bit of
trouble when i am panning/zooming/rotating the canvas. i cannot sync
panning/zooming/rotating of the shape together with the canvas while
dragging. the shape only updates after the mouse button is released.

cpu usage is more worse with larger canvas dimension, right? my canvas is
currently 10k pixels x 10k pixels and contains a lot of lines/paths, texts
and shapes (a map of a city). i am planning to reduce the dimension by
atleast half or use glass pane. and the question is : what would you
recommend? stick with the overlay/immediateRepaint() and reduce the
dimension of the svg or use glass pane?

here is the code of my interactor :

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.swing.gvt.InteractorAdapter;
import org.apache.batik.swing.gvt.JGVTComponent;
import org.apache.batik.swing.gvt.Overlay;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGLocatable;
import org.w3c.dom.svg.SVGMatrix;
import org.w3c.dom.svg.SVGPoint;
import org.w3c.dom.svg.SVGRect;
import org.w3c.dom.svg.SVGSVGElement;

public class CustomInteractor extends InteractorAdapter {

    protected boolean finished = true;
    protected boolean isHandle = false;
    protected float xStart;
    protected float yStart;
    protected float xEnd;
    protected float yEnd;
    protected Line2D line;
    protected Shape shape;
    protected Overlay overlay = new LineOverlay();
    protected BasicStroke markerStroke = new BasicStroke(2,
            BasicStroke.CAP_SQUARE,
            BasicStroke.JOIN_MITER,
            5,
            new float[]{5, 5}, 0);
    protected JGVTComponent source;
    JSVGCanvas at;

    @Override
    public boolean startInteraction(InputEvent ie) {
        return true;
    }

    @Override
    public boolean endInteraction() {
        return finished;
    }

    private Point2D getCanvasCoordinate(Point2D p) {
        Point2D pt = p;
        try {
            AffineTransform bt =
source.getRenderingTransform().createInverse();
            return bt.transform(p, null);
        } catch (NoninvertibleTransformException ex) {
            return pt;
        }
    }

    private Element getElementAt(JGVTComponent source, float x, float y) {
        Point2D p = getCanvasCoordinate(new Point2D.Float(x, y));
        GraphicsNode gn = source.getGraphicsNode().nodeHitAt(p);
        BridgeContext bc =
                ((JSVGCanvas) source).getUpdateManager().getBridgeContext();
        return (Element) bc.getElement(gn);
    }

    public SVGPoint localPt(JGVTComponent c, Element el, float x, float y) {
        SVGSVGElement svgRoot = ((JSVGCanvas)
c).getSVGDocument().getRootElement();
        SVGMatrix mat = ((SVGLocatable) el).getScreenCTM();
        SVGMatrix imat = mat.inverse();
        SVGPoint cPt = svgRoot.createSVGPoint();
        cPt.setX(x);
        cPt.setY(y);
        cPt = cPt.matrixTransform(imat);
        return cPt;
    }

    @Override
    public void mousePressed(MouseEvent e) {
        JGVTComponent c = source = (JGVTComponent) e.getSource();
        at = ((JSVGCanvas) c);
        finished = false;
        line = null;
        Element domE = getElementAt(c, e.getX(), e.getY());
        if ("handle1".equals(domE.getAttribute("id"))) {
            isHandle = true;
            xStart = Float.parseFloat(domE.getAttribute("cx"));
            yStart = Float.parseFloat(domE.getAttribute("cy"));
            SVGRect bbox = ((SVGLocatable) domE).getBBox();
            shape = new Rectangle2D.Float(bbox.getX(), bbox.getY(),
bbox.getWidth(), bbox.getHeight());
        } else {
            shape = null;
        }
        if (!c.getOverlays().contains(overlay)) {
            c.getOverlays().add(overlay);
        }
        c.immediateRepaint();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        JGVTComponent c = (JGVTComponent) e.getSource();
        finished = true;
        isHandle = false;
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        JGVTComponent c = (JGVTComponent) e.getSource();
        if (isHandle) {

            Element domE = getElementAt(c, e.getX(), e.getY());
            SVGPoint pt = localPt(c,
((JSVGCanvas)c).getSVGDocument().getRootElement(), e.getX(), e.getY());
                xEnd = pt.getX();
                yEnd = pt.getY();
            line = new Line2D.Float(xStart, yStart, xEnd, yEnd);
        }
        c.immediateRepaint();
    }

    protected class LineOverlay implements Overlay {

        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.transform(at.getViewBoxTransform());
            g2d.setXORMode(Color.white);
            g2d.setColor(Color.red);
            g2d.setStroke(markerStroke);

            if (line != null) {
                g2d.draw(line);
            }
            if (shape != null) {
                g2d.draw(shape);
            }
        }
    }
}

-- 
View this message in context: 
http://www.nabble.com/getting-the-element-in-svg-from-an-overlay-tp18301441p18724891.html
Sent from the Batik - Users mailing list archive at Nabble.com.


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

Reply via email to