0

I'm trying to add an event handler to a canvas which removes itself when a condition is fulfilled.

I tried doing this, but I'm getting an error which says the variable may have not been initialized.

EventHandler<MouseEvent> canvasHandler = e -> {
        double x = e.getX();
        double y = e.getY();

        boolean last = false;

        if (Math.abs(x - lastX) < 20f) x = lastX;
        if (Math.abs(y - lastY) < 20f) y = lastY;

        if (points.size() > 2) {
            if (Math.abs(x - points.get(0).getKey()) < 20f && Math.abs(y - points.get(0).getValue()) < 20f) {
                x = points.get(0).getKey();
                y = points.get(0).getValue();
                last = true;
            }
        }

        points.add(new Pair<Double, Double>(x, y));

        lastX = x;
        lastY = y;

        gc.lineTo(x, y);

        if (!last) 
            gc.strokeOval(x - 5f, y - 5f, 10f, 10f);
        else
            canvas.removeEventHandler(MouseEvent.MOUSE_CLICKED, canvasHandler);


        gc.stroke();
    };

    canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, canvasHandler);
AwesomeGuy
  • 537
  • 1
  • 6
  • 17

1 Answers1

3

If you use an anonymous class instead of a lambda you can reference the EventHandler with this from inside the handle method:

EventHandler<MouseEvent> canvasHandler = new EventHandler<>() {
  @Override public void handle(MouseEvent event) {
    // handle event...
    if (/* condition */) {
      canvas.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
});
canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, canvasHandler);
Slaw
  • 37,820
  • 8
  • 53
  • 80
  • I'm aware of that option. But isn't it possible to do the same with lambda expressions? – AwesomeGuy Oct 25 '19 at 08:11
  • If `canvasHandler` is a local variable then no. Not unless you want to wrap the instance in another object such as an `AtomicReference` or an array; however, in my opinion, that option is just as verbose as an anonymous class but not as clear. If you make `canvasHandler` a field then you can reference the field from inside the lambda—but not if you initialize the field in the declaration. Using a field also introduces the risk of reassigning the field before the `EventHandler` can remove itself. – Slaw Oct 25 '19 at 08:17