JavaFX removeEventHandler无法按预期工作

时间:2019-10-10 14:18:14

标签: javafx eventhandler

我正在尝试从FontAwesomeIconView对象中删除事件处理程序,但是它不起作用。事件处理程序继续工作,我不知道为什么。

EventHandler<MouseEvent> glowIcon = (e) -> {
        FontAwesomeIconView icon = (FontAwesomeIconView) e.getSource();

        icon.setFill(Color.web("#ffb521"));
        scene.setCursor(Cursor.HAND);
    };

    EventHandler<MouseEvent> unglowIcon = (e) -> {
        FontAwesomeIconView icon = (FontAwesomeIconView) e.getSource();

        icon.setFill(Color.web("#000000"));
        scene.setCursor(Cursor.DEFAULT);
    };

    if (Session.getSession().isProjectCreator()) {
        newIcon.setFill(Color.web("#000000"));
        newIcon.addEventHandler(MouseEvent.MOUSE_ENTERED, glowIcon);
        newIcon.addEventHandler(MouseEvent.MOUSE_EXITED, unglowIcon);
    }else {

        newIcon.setFill(Color.web("#e8e8e8")); //It's changed to this color
        newIcon.removeEventHandler(MouseEvent.MOUSE_ENTERED, glowIcon);
        newIcon.removeEventHandler(MouseEvent.MOUSE_EXITED, unglowIcon);
    }

一开始,事件处理程序已添加,但是当我删除它们时,它们将继续工作,而不应。

2 个答案:

答案 0 :(得分:1)

在看不到最小的可复制示例的情况下,很难说出来。您发布的代码中最有可能出现的情况是,在添加处理程序或删除处理程序时,glowIcon / unglowIncon指向不同的lambda。

每次运行此代码时,即使所有内容完全相同,也会为这些变量分配不同的lambda引用。

EventHandler<MouseEvent> glowIcon = (e) -> {
    FontAwesomeIconView icon = (FontAwesomeIconView) e.getSource();

    icon.setFill(Color.web("#ffb521"));
    scene.setCursor(Cursor.HAND);
};

解决方案是确保仅调用它们一次,并且对它们的引用会在需要时保留在您的控制器中。使用final是一种很好的防御技术,可以确保您不会在某个地方意外地将其重新分配,并且不会丢失删除处理程序所需的引用。

类似的东西:

public class GlowController {
    private final EventHandler<MouseEvent> glowIcon = (e) -> {
        FontAwesomeIconView icon = (FontAwesomeIconView) e.getSource();

        icon.setFill(Color.web("#ffb521"));
        scene.setCursor(Cursor.HAND);
    };

    private final EventHandler<MouseEvent> unglowIcon = (e) -> {
        FontAwesomeIconView icon = (FontAwesomeIconView) e.getSource();

        icon.setFill(Color.web("#000000"));
        scene.setCursor(Cursor.DEFAULT);
    };

    public void doSomething() {
        if (Session.getSession().isProjectCreator()) {
            newIcon.setFill(Color.web("#000000"));
            newIcon.addEventHandler(MouseEvent.MOUSE_ENTERED, glowIcon);
            newIcon.addEventHandler(MouseEvent.MOUSE_EXITED, unglowIcon);
        }else {

            newIcon.setFill(Color.web("#e8e8e8")); //It's changed to this color
            newIcon.removeEventHandler(MouseEvent.MOUSE_ENTERED, glowIcon);
            newIcon.removeEventHandler(MouseEvent.MOUSE_EXITED, unglowIcon);
        }
    }
}

答案 1 :(得分:0)

万一有人在试图找出删除事件侦听器添加的原因时偶然发现:

vbox.setOnMouseClicked(eventHandler);

不要被 removeEventHandler 删除。事实证明,您需要使用以下方法添加事件处理程序:

vbox.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);

为了使删除调用起作用。

我本以为无论您添加处理程序的方式如何,它都会起作用,但事实并非如此:|