首页 > 解决方案 > 匿名 EventHandler 不会自行移除

问题描述

我在控制器类中有以下代码:

public void chooseFromBox() {
    for (Node n : myHbox.getChildren()) {
        ScaleTransition transition = new ScaleTransition(Duration.seconds(0.3), n);
        transition.setByX(0.7);
        transition.setByY(0.7);
        transition.setAutoReverse(true);
        transition.setCycleCount(2);
        transition.play();
        n.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                transition.stop();
                int i = myHbox.getChildren().indexOf(event.getSource());
                for (Node n : myHbox.getChildren()) {
                    n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
                    // This instruction doesn't seem to work
                }
                gui.getNetworkHandler().doSomething(i);
            }
        });
    }
}

在单击其中一个孩子后,我需要 EventHandler 立即消失。与n.removeHandler(MouseEvent.MOUSE_CLICKED, this);被执行的行(我可以从调试中看到)但是在chooseFromBox()方法完成后,我可以再次单击其中一个孩子,它会再次触发。

编辑:遵循@Itai 的建议后,我将代码更改为:

public void chooseFromBox() {
    for (Node n : myHbox.getChildren()) {
        ScaleTransition transition = new ScaleTransition(Duration.seconds(0.3), n);
        transition.setByX(0.7);
        transition.setByY(0.7);
        transition.setAutoReverse(true);
        transition.setCycleCount(2);
        transition.play();
        EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                transition.stop();
                int i = myHbox.getChildren().indexOf(event.getSource());
                n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
                gui.getNetworkHandler().doSomething(i);
            }
        };
        n.setOnMouseClicked(handler);
    }
}

我有另一种类似的方法,但同样的方法不起作用:

void useThing(ActionEvent event) {
    for (Node n : otherHbox.getChildren()) {
        EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                int i = otherHbox.getChildren().indexOf(event.getSource());
                for (Node n : otherHbox.getChildren()) {
                    n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
                }
                gui.getNetworkHandler().doSomethingElse(i);
            }
        };
        n.setOnMouseClicked(handler);
    }
}

我错过了什么?

标签: javaeventsjavafxevent-handling

解决方案


也许尝试换掉这个

    EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            transition.stop();
            int i = myHbox.getChildren().indexOf(event.getSource());
            n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
            gui.getNetworkHandler().doSomething(i);
        }
    };
    n.setOnMouseClicked(handler);

有了这个

    n.setOnMouseClicked(event -> {
        transition.stop();
        int i = myHbox.getChildren().indexOf(event.getSource());
        //n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
        n.setOnMouseClicked(Event::consume);
        gui.getNetworkHandler().doSomething(i);
    });

同样交换这个

    EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            int i = otherHbox.getChildren().indexOf(event.getSource());
            for (Node n : otherHbox.getChildren()) {
                n.removeEventHandler(MouseEvent.MOUSE_CLICKED, this);
            }
            gui.getNetworkHandler().doSomethingElse(i);
        }
    };
    n.setOnMouseClicked(handler);

有了这个

    n.setOnMouseClicked(event -> {
        int i = otherHbox.getChildren().indexOf(event.getSource());
        for (Node node : otherHbox.getChildren()) {
            node.setOnMouseClicked(Event::consume);
        }
        gui.getNetworkHandler().doSomethingElse(i);
    });

我在测试中使用了消耗来删除您可能想要更改的事件,具体取决于您在做什么


推荐阅读