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 Age Bosma <ag...@gmail.com> on 2009/03/09 11:28:45 UTC

Unable to remove event listener

Hi,

I'm trying to remove an event listener but for some reason this doesn't work.

I'm creating a new element to add to the JSVGCanvas. To add an event
listener I use:

-----------------------------------------------------------------------------------
((EventTarget)device).addEventListener("mousedown", new DeviceHandler(), false);
-----------------------------------------------------------------------------------

This works fine. The event gets triggered as it should. The event is
used to drag an element. When it gets triggered I'm adding two new
events to the same element. These get triggered nicely as well but I
can't get them removed anyone.
The code:


-----------------------------------------------------------------------------------
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MouseEvent;
import org.w3c.dom.svg.SVGElement;
import org.w3c.dom.svg.SVGLocatable;
import org.w3c.dom.svg.SVGMatrix;
import org.w3c.dom.svg.SVGPoint;

public class DeviceHandler implements EventListener {
  DeviceHandler() {
  }
    DeviceHandler(float startX, float startY) {
      this.startX = startX;
      this.startY = startY;
  }

  @Override
  public void handleEvent(Event evt) {
      String eventType = evt.getType();
      System.out.println("Event type: " + eventType);
      targetElement = (SVGElement) evt.getTarget();
      System.out.println("Target: " + targetElement.getTagName());
      event = (MouseEvent) evt;

      SVGMatrix mat =
((SVGLocatable)targetElement.getOwnerSVGElement()).getScreenCTM();
      SVGMatrix imat = mat.inverse();
      position = targetElement.getOwnerSVGElement().createSVGPoint();

      position.setX((float) event.getClientX());
      position.setY((float) event.getClientY());

      position = position.matrixTransform(imat);

      if (eventType.equals("mousedown")) {
          startX = position.getX();
          startY = position.getY();

          ((EventTarget)targetElement).addEventListener("mousemove",
new DeviceHandler(startX, startY), false);
          ((EventTarget)targetElement).addEventListener("mouseup", new
DeviceHandler(), false);
      }
      else if (eventType.equals("mousemove")) {
          double x = position.getX() - startX;
          double y = position.getY() - startY;

          System.out.println("Translate: x=" + x + ", y=" + y);

          targetElement.setAttributeNS(null, "transform", "translate("
+ x + "," + y + ")");
          targetElement.setAttributeNS(null, "stroke", "rgb(255,0,0)");
      }
      else if (eventType.equals("mouseup")) {
          ((EventTarget)targetElement).removeEventListener("mousemove",
new DeviceHandler(), false);
          ((EventTarget)targetElement).removeEventListener("mouseup",
new DeviceHandler(), false);
      }
  }

  private SVGElement targetElement = null;
  private MouseEvent event;
  private float startX = 0;
  private float startY = 0;
  private SVGPoint position;
}
-----------------------------------------------------------------------------------

Intended bahaviour: mousedown+ mousemove = drag. It should remove the
'mousemove' and 'mouseup' again when the button is let go.
I tried replacing 'new DeviceHandler()' with 'this' when removing the
events but 'mousemove' nor 'mouseup' gets removed, they remain getting
triggered. As a result you can't stop dragging the element.
As I test I even added removeEventListener right after a
addEventListener but the event does not get removed, it keeps getting
trigered.

I'm I doing something completely wrong here?

Yours,

Age

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


Re: Unable to remove event listener

Posted by Age Bosma <ag...@gmail.com>.
I forgot to include some info:

Batik: batik-src-09-02-20
Java: jdk1.6.0_12
OS: Windows XP SP3

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


Re: Unable to remove event listener

Posted by th...@kodak.com.
Hi Age,

> 2009/3/28  <th...@kodak.com>:

> >    I'm fairly certain that modifying the pointer-events property works
> > in Batik.  So I suspect the issue is most likely that you are setting 
the
> > pointer-events property to all on the wrong element (try printing the

Age Bosma <ag...@gmail.com> wrote on 03/30/2009 05:26:46 AM:

> It's the correct element. I did double check to make sure but it
> couldn't be on the wrong one since I'm storing the same element and
> move it later on.

   Then I suggest you produce a reduced test case to demonstrate
the problem.

> I did notice some inconsistencies. The problem occurs most of the
> times, though not all the time. Every once and a while it is possible
> to start dragging the element by clicking anywhere on the complete
> surface after a couple of drags.

   This sounds less and less like a Batik problem and more like a
problem in your event handling code.  Do you make sure to do all
modifications in the UpdateManager Runnable Thread?

   Unless you can produce a reduced version of the problem I
don't think I can help as I've never encountered what you are
describing.

Re: Unable to remove event listener

Posted by Age Bosma <ag...@gmail.com>.
Thanks for you reply Thomas,

2009/3/28  <th...@kodak.com>:
>
> Hi Age,
>
> Age Bosma <ag...@gmail.com> wrote on 03/27/2009 05:30:33 AM:
>
>> I've determined that the cause of this issue is the pointer event
>> changes on deviceElement. First setting it to none on mousedown and
>> setting it to all again on mouse up gives this problem. If I leave the
>> pointer event as is, all works like expected.
>
>    I'm fairly certain that modifying the pointer-events property works
> in Batik.  So I suspect the issue is most likely that you are setting the
> pointer-events property to all on the wrong element (try printing the

It's the correct element. I did double check to make sure but it
couldn't be on the wrong one since I'm storing the same element and
move it later on.

> element you set the property on).  Also you might check that you aren't
> manipulating the style in one case and the attribute in the other case.
>

I'm creating the elements to be moved in Java. Nothing other then
setAttributeNS() is ever used. I'm not setting any styles.

I check the initial states just to be sure. When I set the
pointer-event to 'none' for the first time, pointer-events is empty,
which shouldn't be a problem. According to the specs it should at
least default to 'visiblePainted' so instead of setting it to 'all'
after the drag I tried that value as well. Unfortunately with the same
result. A forced setting to 'all' when creating the element also makes
no difference.

I did notice some inconsistencies. The problem occurs most of the
times, though not all the time. Every once and a while it is possible
to start dragging the element by clicking anywhere on the complete
surface after a couple of drags. This only ones or twice before
falling back to the old behaviour followed by working properly again
after a couple of drags, etc. Obviously this only goes when doing the
dragging in combination with the line movement. If not I'm not able to
move the element in the first place.

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


Re: Unable to remove event listener

Posted by th...@kodak.com.
Hi Age,

Age Bosma <ag...@gmail.com> wrote on 03/27/2009 05:30:33 AM:

> I've determined that the cause of this issue is the pointer event
> changes on deviceElement. First setting it to none on mousedown and
> setting it to all again on mouse up gives this problem. If I leave the
> pointer event as is, all works like expected.

   I'm fairly certain that modifying the pointer-events property works
in Batik.  So I suspect the issue is most likely that you are setting the
pointer-events property to all on the wrong element (try printing the
element you set the property on).  Also you might check that you aren't
manipulating the style in one case and the attribute in the other case.

> I do, however, need to remove the pointer event temporarily. Otherwise 
> the target will always be the draggable element on mouseup. This 
prevents 
> me from determining the drop target, i.e. the underlying element.

    Sure, I've done similar things in the past, which is why I think
manipulating pointer events works...

Re: Unable to remove event listener

Posted by Age Bosma <ag...@gmail.com>.
2009/3/10 Age Bosma <ag...@gmail.com>:

> If I leave out the 'way point' movement bit (i.e. I move the line path
> begin point in accordance to the circle drag movement) in the code
> above I get the problem I mentioned above. I can not move the circle
> for a second time.
> However, if I do move the line along with the circle, I can drag the
> circle multiple times but the mouse down event only gets triggered
> again if the mouse is positioned (clicked) within the overlapping bit
> of the circle and the bbox of the path element :-S Thus not in any
> other part of the circle element. How can this be?
>

I've determined that the cause of this issue is the pointer event
changes on deviceElement. First setting it to none on mousedown and
setting it to all again on mouse up gives this problem. If I leave the
pointer event as is, all works like expected. I do, however, need to
remove the pointer event temporarily. Otherwise the target will always
be the draggable element on mouseup. This prevents me from determining
the drop target, i.e. the underlying element.

Any idea's on how to address this issue?

Age

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


Re: Unable to remove event listener

Posted by Age Bosma <ag...@gmail.com>.
2009/3/9  <th...@kodak.com>:
>
> Hi Age,
>
> Age Bosma <ag...@gmail.com> wrote on 03/09/2009 06:28:45 AM:
>
>> This works fine. The event gets triggered as it should. The event is
>> used to drag an element. When it gets triggered I'm adding two new
>> events to the same element. These get triggered nicely as well but I
>> can't get them removed anyone.
>
>    You need to pass the same object as the second argument to
> removeEventListener as you passed to addEventListener.  I
> suspect you might be best off passing 'this' for all of the objects
> (and setting startX/Y on this on mousedown).
>

Thanks Thomas, that did the trick! Some additional alterations where
required to make it all work but using 'this' for all the event
listeners was the important bit.

There's still something weird going on with the dragging part though.
At first I added the move and up event listeners to the element that
had to be dragged. This did work fine up to the point where I moved
the mouse to fast. It lost focus when doing so. Because of this I
moved the additional event listeners to the background element. This
does work...but only for the first time. After I dragged it ones and
let it go, I can't drag it for a second time. No mouse down event gets
triggered on the element any more.

This is what I've got now:

--------------------------------------------------------
public class DeviceHandler implements EventListener {
  DeviceHandler() {
  }

  @Override
  public void handleEvent(Event evt) {
      String eventType = evt.getType();
      MouseEvent event = (MouseEvent) evt;

      SVGElement eventTarget = (SVGElement) evt.getTarget();
      SVGElement backgroundElement = (SVGElement)
eventTarget.getOwnerSVGElement().getElementById("background");

      // Determine our mouse position on the SVG canvas
      SVGMatrix mat =
((SVGLocatable)eventTarget.getOwnerSVGElement()).getScreenCTM();
      SVGMatrix imat = mat.inverse();
      mousePosition = eventTarget.getOwnerSVGElement().createSVGPoint();
      mousePosition.setX((float) event.getClientX());
      mousePosition.setY((float) event.getClientY());
      mousePosition = mousePosition.matrixTransform(imat);

      if (eventType.equals("mousedown")) {
          deviceElement = (SVGElement) evt.getTarget();

          startX = mousePosition.getX();
          startY = mousePosition.getY();

          ((EventTarget)backgroundElement).addEventListener("mousemove",
this, false);
          ((EventTarget)backgroundElement).addEventListener("mouseup",
this, false);
          deviceElement.setAttributeNS(null, "pointer-events", "none");
          backgroundElement.setAttributeNS(null, "pointer-events", "all");
      }
      else if (eventType.equals("mousemove")) {
          // Determine the new target position and move it
          newX = (mousePosition.getX() - startX) + offsetX;
          newY = (mousePosition.getY() - startY) + offsetY;
          deviceElement.setAttributeNS(null, "transform", "translate("
+ newX + "," + newY + ")");

          // Get the target's way point line
          SVGOMPathElement pathElement = (SVGOMPathElement)
deviceElement.getOwnerSVGElement().getElementById("device_path_" +
deviceElement.getId().substring(14));
          SVGPathSegMovetoAbs pathSeg = (SVGPathSegMovetoAbs)
pathElement.getPathSegList().getItem(0);
                    // Set the starting position of the way point line
to the center of the target's new location
          SVGRect targetBBox = ((SVGLocatable)deviceElement).getBBox();
          pathSeg.setX(targetBBox.getX() + (targetBBox.getWidth() / 2) + newX);
          pathSeg.setY(targetBBox.getY() + (targetBBox.getHeight() / 2) + newY);
      }
      else if (eventType.equals("mouseup")) {
          offsetX = newX;
          offsetY = newY;

          ((EventTarget)backgroundElement).removeEventListener("mousemove",
this, false);
          ((EventTarget)backgroundElement).removeEventListener("mouseup",
this, false);
          deviceElement.setAttributeNS(null, "pointer-events", "all");
          backgroundElement.setAttributeNS(null, "pointer-events", "none");
      }
  }

  private SVGElement deviceElement = null;
  private float startX;
  private float startY;
  private float offsetX = 0;
  private float offsetY = 0;
  private float newX;
  private float newY;
  private SVGPoint mousePosition;
}
--------------------------------------------------------

It gets called the same way as before. When I add the element to the
canvas, I also add the mousedown event listener. At the same moment as
I added the element which has to be dragged (circle) I'm adding a path
(straight line) from that element centre to the centre of the canvas
as well.
If I leave out the 'way point' movement bit (i.e. I move the line path
begin point in accordance to the circle drag movement) in the code
above I get the problem I mentioned above. I can not move the circle
for a second time.
However, if I do move the line along with the circle, I can drag the
circle multiple times but the mouse down event only gets triggered
again if the mouse is positioned (clicked) within the overlapping bit
of the circle and the bbox of the path element :-S Thus not in any
other part of the circle element. How can this be?

Yours,

Age

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


Re: Unable to remove event listener

Posted by th...@kodak.com.
Hi Age,

Age Bosma <ag...@gmail.com> wrote on 03/09/2009 06:28:45 AM:

> This works fine. The event gets triggered as it should. The event is
> used to drag an element. When it gets triggered I'm adding two new
> events to the same element. These get triggered nicely as well but I
> can't get them removed anyone.

   You need to pass the same object as the second argument to 
removeEventListener as you passed to addEventListener.  I
suspect you might be best off passing 'this' for all of the objects
(and setting startX/Y on this on mousedown).

>           ((EventTarget)targetElement).addEventListener("mousemove", new 
DeviceHandler(startX, startY), false);
>           ((EventTarget)targetElement).addEventListener("mouseup", new 
DeviceHandler(), false);
>       }
>       else if (eventType.equals("mousemove")) {
>           double x = position.getX() - startX;
>           double y = position.getY() - startY;
> 
>           System.out.println("Translate: x=" + x + ", y=" + y);
> 
>           targetElement.setAttributeNS(null, "transform", "translate("
> + x + "," + y + ")");
>           targetElement.setAttributeNS(null, "stroke", "rgb(255,0,0)");
>       }
>       else if (eventType.equals("mouseup")) {
>           ((EventTarget)targetElement).removeEventListener("mousemove",
> new DeviceHandler(), false);
>           ((EventTarget)targetElement).removeEventListener("mouseup",
> new DeviceHandler(), false);
>       }
>   }
> 
>   private SVGElement targetElement = null;
>   private MouseEvent event;
>   private float startX = 0;
>   private float startY = 0;
>   private SVGPoint position;
> }
> 
-----------------------------------------------------------------------------------
> 
> Intended bahaviour: mousedown+ mousemove = drag. It should remove the
> 'mousemove' and 'mouseup' again when the button is let go.
> I tried replacing 'new DeviceHandler()' with 'this' when removing the
> events but 'mousemove' nor 'mouseup' gets removed, they remain getting
> triggered. As a result you can't stop dragging the element.
> As I test I even added removeEventListener right after a
> addEventListener but the event does not get removed, it keeps getting
> trigered.
> 
> I'm I doing something completely wrong here?
> 
> Yours,
> 
> Age
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
> For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org
>