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);
0

1 Answer 1

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);
Sign up to request clarification or add additional context in comments.

2 Comments

I'm aware of that option. But isn't it possible to do the same with lambda expressions?
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.