JavaFx 的 setOnAction 方法是如何工作的?

How does JavaFx's setOnAction method work under the hood?

在我的面向对象编程 class 中,我们最近的主题是通过 JavaFX 进行事件驱动编程。这些概念相对有趣,尽管有时让我很困惑。我很难理解的一件事是 setOnAction() 方法的工作原理。

正如我的导师所说,此方法接收一个 class 的对象,该对象具有 handle 方法,并在触发事件时调用该 handle 方法。

例如在我们的start方法中:

class MyHandler implements EventHandler<ActionEvent> {
        @Override
        public void handle(ActionEvent actionEvent) {
            System.out.println("Handled");
        }
    }

Button button = new Button();
button.setOnAction(new MyHandler());

但是,我无法理解其背后的原理。 setOnAction 方法究竟是如何“知道”调用 MyHandler 对象的句柄方法的?是否可以实现我自己的 setOnAction 版本,在其中调用任何传入对象的特定命名方法?

如果我们根本不实现 handle 方法,而是说 fakeHandle 方法,就像这样。

class MyHandler {
        public void fakeHandle(ActionEvent actionEvent) {
            System.out.println("Handled");
        }
    }

Button button = new Button();
button.setOnAction(new MyHandler());

我们的代码还能用吗?

As my instructor said, this method takes in an object of a class that has a handle method, and calls that handle method whenever an event is fired.

我怀疑这里有轻微的误解或用词不当。您不能将 class 定义了 handle(ActionEvent) 方法的任意对象传递给 setOnAction 方法。 setOnAction 方法被定义为接受 EventHandler<ActionEvent> 实现, 接口 定义了 handle 方法。

这正是接口的用途。它们定义了所有实现都必须遵循的契约。只要它的 class 实现 EventHandler<ActionEvent>,传递给 setOnAction 的对象并不重要。这就是 JavaFX 了解 handle 方法的方式,因为它了解 EventHandler 接口。

您的第二个代码示例无法编译,因为 myHandler 未实现 EventHandler<ActionEvent>。但即使它执行了,您的 fakeHandle 方法也不会被调用(通过 JavaFX 代码),因为 JavaFX 不知道它。


准确解释整个 event-handling 过程如何在 JavaFX 中工作 under-the-hood 是一个 in-depth 过程。如果你真的想理解这一点,那么我建议阅读代码——JavaFX is open source. However, if you only want to understand event-handling from a user's perspective (i.e. an API level) then this tutorial 应该有所帮助。