【问题标题】:JavaFX remove eventhandler from lambda expression [duplicate]JavaFX从lambda表达式中删除事件处理程序[重复]
【发布时间】:2019-10-25 07:49:19
【问题描述】:

我正在尝试将事件处理程序添加到画布,当条件满足时它会自行移除。

我尝试这样做,但我收到一条错误消息,提示变量可能尚未初始化。

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

【问题讨论】:

    标签: javafx lambda eventhandler


    【解决方案1】:

    如果您使用匿名类而不是 lambda,您可以在 handle 方法内部使用 this 引用 EventHandler

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

    【讨论】:

    • 我知道这个选项。但是难道不能用 lambda 表达式做同样的事情吗?
    • 如果canvasHandler 是一个局部变量,那么不是。除非您想将实例包装在另一个对象中,例如 AtomicReference 或数组;但是,在我看来,该选项与匿名类一样冗长,但并不清晰。如果您将canvasHandler 设为一个字段,那么您可以从 lambda 内部引用该字段——但如果您在声明中初始化该字段,则不能。使用字段还会带来在EventHandler 自行删除之前重新分配字段的风险。
    猜你喜欢
    • 2020-01-12
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    相关资源
    最近更新 更多