Java FX - 事件处理的不同方面

Tra*_*ity 5 java javafx event-handling propertychangelistener

我试图了解 Java FX 中事件处理的不同方面。我已经通读了 Oracle 材料,但我仍然有点困惑,想知道是否有人能以简洁的方式解释一些不同选项的差异和主要用途。

首先,据我所知,有事件处理程序和事件过滤器,然后是方便的方法。那么处理程序和过滤器之间的主要区别是什么,为什么我会使用一个而不是另一个。此外,使用 addEventHandler(...) 而不是使用便捷方法添加事件处理程序有什么好处?根据我自己的测试,我相信使用 addEventHandler(...) 可以将多个事件处理程序附加到给定的控件,而使用 setOnEvent-type(...) 只允许附加一个事件处理程序,因为它每次都会覆盖该属性它被设置。还有其他区别吗?

然后是 ChangeListener 和 InvalidationListener 的主题 - 我是否认为 ChangeListener 是一种事件处理程序,专门设计用于侦听(属性)更改事件?除了 JavaFX 属性和绑定上的 Oracle 页面之外,我似乎找不到许多使用 ChangeListener 的示例 - 有没有人知道一个好的指南?此外,简单来说,我什么时候会在 ChangeListener 和 InvalidationListener 之间进行选择?

最后,有时是否可以通过传统的 EventHandler 或 ChangeListener 模拟相同的事件处理过程 - 例如,可以使用 ActionEvent 处理按钮单击 - 有没有办法通过 ChangeListener 来完成?我可以看到理论上您可以向 onActionProperty 添加更改侦听器,但我认为单击按钮时不会调用此方法,而是如果 setOnAction 实际更改了附加的事件处理程序?

Alm*_*asB 3

那么处理程序和过滤器之间的主要区别是什么以及为什么我会使用其中一个而不是另一个。

关键的区别在于每个事件发生的时间。事件过滤器在事件捕获阶段调用,该阶段发生在事件冒泡阶段(调用事件处理程序)之前。因此,您可以在通知处理程序之前过滤(使用)您不想处理的事件。大多数时候,您只想使用处理程序而不用担心过滤器。但是,在某些情况下您需要过滤事件。例如,想象一个游戏,其中鼠标处理程序移动游戏角色。如果用户打开游戏内菜单,您不希望他能够“通过”菜单单击进入游戏并在菜单打开时移动角色。一种可能的方法是过滤这些鼠标事件并在它们到达注册处理程序的节点之前使用它们。您当然可以将鼠标处理程序附加到不同的东西而不是整个场景,但这超出了示例中强调的要点。

顾名思义,便利处理程序是为了方便而存在的。它减少了样板代码并允许简单的 API。根据 JavaFX 文档,它们在事件链中最后被调用。因此,如果您只对一种事件类型感兴趣,那么应该首选这些方法。

总而言之,按此顺序使用便利性和事件处理程序,如果需要对事件分派进行更多控制,您还可以添加过滤器。

此外,简单来说,什么时候我会在 ChangeListener 和 InvalidationListener 之间进行选择?

当值实际上发生更改时,更改侦听器会收到通知。为了识别变化,必须重新计算该值。因此,当您将这样的侦听器添加到可观察值时,它不再是延迟评估,而是急切评估。

当值不再有效时,无效侦听器会收到通知。然而,这并不意味着价值已经改变。这允许我们在实际不知道值的情况下触发失效事件。该值将在被访问之前被评估。

所以,简单来说,如果需要知道可观察对象的新值,请使用 ChangeListener,否则使用 InvalidationListener。

我可以看到理论上您可以向 onActionProperty 添加一个更改侦听器,但我认为单击按钮时不会调用此侦听器,而是如果 setOnAction 实际上更改了附加的事件处理程序?

是的你是对的。要处理按钮单击,您需要使用setOnAction(). ChangeListener与事件处理无关。