【问题标题】:JavaFX removeEventHandler not working as expectedJavaFX removeEventHandler 未按预期工作
【发布时间】:2019-10-10 14:18:14
【问题描述】:

我正在尝试从 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);
    }

一开始添加了事件处理程序,但是当我删除它们时,它们会继续工作,而它们不应该这样做。

【问题讨论】:

标签: javafx eventhandler


【解决方案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);
        }
    }
}

【讨论】:

    【解决方案2】:

    如果有人在试图弄清楚为什么删除事件侦听器会添加以下内容时偶然发现:

    vbox.setOnMouseClicked(eventHandler);
    

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

    vbox.addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
    

    删除调用工作。

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

    【讨论】:

    • 这是正确答案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2021-06-04
    • 2022-01-24
    • 2015-05-11
    • 2020-05-15
    • 2014-10-31
    相关资源
    最近更新 更多