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 Händel <mi...@gmx.de> on 2003/01/15 19:17:48 UTC

Batik: MouseEventListener for the JSVGCanvas returns wrong coordinates

Hello to everyone,

does anybody got an idea how to add an MouseEventListener to the JSVGCanvas
which gets the correct SVG coordinates??

I want to do the following: I've got an element in the canvas and want to
move it by mouseclick. So far I can drag and drop the element with the
"mousedown", "mousedown" and "mousemove" events... but if I move the mouse
quickly it seems as if Batik or my computer is too slow, and the cursor is
not anymore over the element and the events get not called anymore.
So my idea was to add an "mouseup" event to the canvas, but the following
code returns different coordinates for the canvas-MouseEvent and the
DOMMouseEvent...

the canvas Listener:
canvas.addMouseListener(new MouseListener(){
   public void mouseReleased(MouseEvent e) {
      }
});

the DOMEventListener:
- initialization:
Element root = document.getElementById("e");
SVGGElement target = (SVGGElement)root;
target.addEventListener("mousemove", new MouseMoveListener(), true);

- class implementation:
public class MouseMoveListener implements EventListener {
    public void handleEvent (Event evt) {
      DOMMouseEvent pos = ((DOMMouseEvent)evt);
}
}

Does anybody have an idea how to get the correct position from the
canvasListener??

Thank you very much in advance...
Michael Händel.

Re: Batik: MouseEventListener for the JSVGCanvas returns wrong coordinates

Posted by Zach Del <zs...@umich.edu>.
Michael Händel wrote:

>  
> Hello to everyone,
>  
> does anybody got an idea how to add an MouseEventListener to the 
> JSVGCanvas which gets the correct SVG coordinates??
>  
> I want to do the following: I've got an element in the canvas and want 
> to move it by mouseclick. So far I can drag and drop the element with 
> the "mousedown", "mousedown" and "mousemove" events... but if I move 
> the mouse quickly it seems as if Batik or my computer is too slow, and 
> the cursor is not anymore over the element and the events get not 
> called anymore.
> So my idea was to add an "mouseup" event to the canvas, but the 
> following code returns different coordinates for the canvas-MouseEvent 
> and the DOMMouseEvent...
>  

The problem is not your computer, but Java -- when you move the mouse 
quickly and press the button, Java interprets that action as a drag 
instead of a click.

However, it can be fixed! I recently just fixed this problem myself. You 
will need to do the following things:
1) subclass JSVGCanvas, JSVGComponent, or JGVTComponent, whatever you 
are using.   You will need to
    override the method createListener() to return your new subclassed 
Listener (see #2)
2) subclass the appropriate Listener class (for JSVGCanvas, it is 
JSVGCanvas.CanvasSVGListener
   
so: in your JSVGCanvas subclass:
<code>
    protected Listener createListener()
    {
        return new BetterCanvasListener();
    }// createListener()
</code>

And here is BetterCanvasListener()

<code>

protected class BetterCanvasListener extends JSVGCanvas.CanvasSVGListener
{
    private int dragX;                            // start drag X coord
    private int dragY;                            // start drag Y coord
    private boolean inDrag = false;                // 'true' if we are 
in a drag (versus a click)
    private final int MIN_DRAG_DELTA = 5;        // less than this == 
click, not a drag; in pixels
   
    public BetterCanvasListener()
    {
    }// BetterCanvasListener()
   
   
    public void mouseDragged(MouseEvent e)
    {
        inDrag = true;
        super.mouseDragged(e);
        //System.out.println("  DRAG: x,y = "+e.getX()+", "+e.getY());
    }// mouseDragged()
   
   
    public void mousePressed(java.awt.event.MouseEvent e)
    {
        // set drag start coordinates
        dragX = e.getX();
        dragY = e.getY();
        super.mousePressed(e);
        //System.out.println("PRESSED: x,y = "+e.getX()+", "+e.getY());
    }// mousePressed()
   
   
    public void mouseReleased(java.awt.event.MouseEvent e)
    {
        //System.out.println("  ** RELEASED: x,y = "+e.getX()+", 
"+e.getY());
        //System.out.println("     indrag? "+inDrag);
        if(inDrag)
        {
            int dx = Math.abs(e.getX() - dragX);
            int dy = Math.abs(e.getY() - dragY);
            //System.out.println("     drag dx,dy: "+dx+", "+dy);
           
            if(dx < MIN_DRAG_DELTA && dy < MIN_DRAG_DELTA)
            {
                // our drag was short! dispatch a new CLICK event.
                MouseEvent click = new MouseEvent(
                    e.getComponent(),
                    MouseEvent.MOUSE_CLICKED,
                    e.getWhen(),
                    e.getModifiersEx(),        // modifiers
                    e.getX(),
                    e.getY(),
                    e.getClickCount(),
                    e.isPopupTrigger(),
                    e.getButton() );
                   
                //System.out.println("clickEvent: "+click);
                super.mouseClicked(click);
            }
            else
            {
                // not a short drag.
                super.mouseReleased(e);
            }
        }
       
        // reset drag
        inDrag = false;
    }// mouseReleased()
   
   
}// class BetterCanvasListener

</code>

I think this class really helps -- this behavior probably should be in 
Batik as a default behavior!

Zach
||


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