java - setOnXXX() 方法和 addEventHandler() JavaFx 之间的区别

标签 java javafx

我正在尝试学习 JavaFX 事件处理。我发现我们可以通过两种方式注册事件。

一种是方便的方法,如 setOnAction(EventHandler)setOnMouseClicked(EventHandler)

第二种是使用 addEventHandler(MouseEvent.MOUSE_CLICKED, EventHandler)

但我很困惑它们之间有什么区别?如何决定哪一个合适?

我已经使用这两种方法测试并注册了两个事件处理程序,并且都工作正常。

Button btn = new Button("Click Me One!");
    btn.setOnMouseEntered(new EventHandler<MouseEvent>(){
        @Override
        public void handle(MouseEvent e){
            System.out.println("Mouse Entered on Click Me One");
        }
    });

    btn.setOnMouseExited(new EventHandler<MouseEvent>(){
        @Override
        public void handle(MouseEvent e){
            System.out.println("Mouse Exited from Click Me One");
        }
    });


    Button btn2 = new Button("Click Me Two!");
    btn2.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>(){
        @Override
        public void handle(MouseEvent e){
            System.out.println("Mouse Entered on Click Me Two");
        }
    });
    btn2.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>(){
        @Override
        public void handle(MouseEvent e){
            System.out.println("Mouse Exited from Click Me Two");
        }
    });

这里是检查后的输出。

Mouse Entered on Click Me One
Mouse Exited from Click Me One
Mouse Entered on Click Me Two
Mouse Exited from Click Me Two

我还通过定义事件处理程序进行了检查。

Button btn2 = new Button("Click Me Two!");
        // Define an event handler
        EventHandler<InputEvent> handler = new EventHandler<InputEvent>() {
            public void handle(InputEvent event) {
                System.out.println("Handling event " + event.getEventType()); 

            }
        };
        btn2.addEventHandler(MouseEvent.MOUSE_ENTERED, handler);
        btn2.addEventHandler(MouseEvent.MOUSE_EXITED, handler);

        btn2.setOnMouseEntered(handler);
        btn2.setOnMouseExited(handler);

输出:

Handling event MOUSE_ENTERED
Handling event MOUSE_ENTERED
Handling event MOUSE_EXITED
Handling event MOUSE_EXITED

最佳答案

self 测试后,我明白了 There can only one handler of same type with convenience method 的含义。所以我要回答我自己的问题。

我发现 setOnXXX() 方法和 addEventHandler 之间有两个主要区别

1:您使用addEventHandler() 注册的事件将首先执行。这是示例。

Button btn = new Button("Hover Me!");

btn.setOnMouseEntered(new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event with Convience Method"); 
    }
});
btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event with addEventHandler"); 
    }
});

输出:

Handling event with addEventHandler
Handling event with Convience Method

阅读James_D 的评论后,我添加了original doc 中的段落对于第一个区别。

A node can register more than one handler. The order in which each handler is called is based on the hierarchy of event types. Handlers for a specific event type are executed before handlers for generic event types. For example, a handler for the KeyEvent.KEY_TYPED event is called before the handler for the InputEvent.ANY event. The order in which two handlers at the same level are executed is not specified, with the exception that handlers that are registered by the convenience methods described in Working with Convenience Methods are executed last.

2: 第二个区别是您可以使用 addEventHandler(); 但在 setOnXXX(); 的情况下,最后注册的事件处理程序将执行。这是示例。

Button btn = new Button("Hover Me!");

btn.setOnMouseEntered(new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event 1 with Convenience Method"); 
    }
});
btn.setOnMouseEntered(new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event 2 with Convenience Method"); 
    }
});
btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event 1 with addEventHandler"); 
    }
});

btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() {
    public void handle(MouseEvent event) {
        System.out.println("Handling event 2 with addEventHandler"); 
    }
});

输出:

Handling event 1 with addEventHandler
Handling event 2 with addEventHandler
Handling event 2 with Convenience Method

如您所见,我使用两种方式注册了两个事件处理程序。但是以方便方法的方式,最后一个事件处理程序被执行。为了完成答案,让我复制 jns 的答案中的段落。

So if you need only one EventHandler it makes no difference which method you use. However, if you need to apply several EventHandlers for the same EventType you have to add them using addEventhandler

关于java - setOnXXX() 方法和 addEventHandler() JavaFx 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37821796/

相关文章:

java - 从 heightProperty() 和 widthProperty() 中获取最大值和最小值

JavaFX hello world 按钮的启动方法不允许 setText 或添加 setOnAction

JavaFX - 更改 slider 特定刻度的颜色

Java - 提取子元素

java - 无法设置 ScrollView 的可见性

java - javafx如何从其他类关闭窗口

java - 使用运行/调试配置在 IntelliJ IDEA 中运行 JavaFX 11 Maven 项目

java - 如何使用 Java MongoDB 驱动程序检索字段的子集?

java - Big Word 应用程序,使用 Canvas Javafx,有趣的挑战

java - libgdxcamera.position.set导致撕裂