JavaFX事件处理之谜 - 代码已删除且事件仍在处理中?

时间:2017-03-31 23:51:28

标签: java events javafx lambda event-handling

我在Java和C#等OOP语言方面经验丰富。直到现在才搞砸FX,并开始在办公室处理无聊的事件。

我的FX应用程序全部写在一个类中。我导入了我想要的包,包括这两个:

import javafx.event.ActionEvent;
import javafx.event.EventHandler;

我在Main类声明上实现了ActionEvent类型的EventHandler接口,如此..

public class Main extends Application implements EventHandler<ActionEvent>

我在按钮对象上写了一个匿名内部类来处理像这样的点击事件。

btnButton.setOnAction(new EventHandler<ActionEvent>(){
        public void handle(ActionEvent event) {
            System.out.println("I got clicked");
        }
});

它显然像它应该的那样工作,但后来我做了一个实验。我从上面删除了两个导入。我删除了Main类声明的“implements”部分。这使我的应用程序没有任何对事件处理的引用。然后我回到我的按钮对象并将事件处理程序编写为lambda表达式,如此...

btnButton.setOnAction(e -> System.out.println("I got touched"));

猜猜是什么?它仍然工作!这是不可能的..在删除处理事件所需的代码后,有人可以解释这仍然有效吗?这很有趣,这让我大吃一惊。

提前感谢您的回复!

-KeplerIO

1 个答案:

答案 0 :(得分:2)

您没有删除事件处理所需的代码:

NoMethodError: undefined method `pluck' for #<Equipment>

从不需要使用public class Main extends Application implements EventHandler<ActionEvent> 类实现EventHandler<ActionEvent>,因为您无论如何使用anonymus类作为事件处理程序,而不是

Main

(假设btnButton.setOnAction(this); 在此引用this个实例)

lambdas的一个好处是,只要java编译器仍然能够明确地确定您正在实现的接口(从而确定方法的签名),就可以省略参数类型。 / p>

在这种情况下,Main方法不会重载,java编译器可以确保参数的类型为setOnAction,并且要实现的方法的签名是

EventHandler<ActionEvent>

因此

public void handle(ActionEvent event)

甚至

btnButton.setOnAction((ActionEvent e) -> System.out.println("I got touched"));

&#34;满足&#34;编译器。

如果btnButton.setOnAction(e -> System.out.println("I got touched")); 方法过载setOnAction

,则会有所不同
Button

在这种情况下,编译器需要其他信息来确定要使用的方法:

public void setOnAction(Consumer<Integer> x) { ... }

如果您有兴趣在规范中查看,请参阅以下相关部分: