5

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

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

然后是 ChangeListener 和 InvalidationListener 的主题 - 我认为 ChangeListener 是一种事件处理程序是正确的吗,它专门用于侦听(属性的)更改事件?除了 JavaFX Properties and Binding 上的 Oracle 页面之外,我似乎找不到很多使用 ChangeListener 的例子——有人知道一个好的指南吗?此外,简单来说,我什么时候可以在 ChangeListener 和 InvalidationListener 之间进行选择?

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

4

1 回答 1

3

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

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

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

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

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

当值实际上已更改时,会通知更改侦听器。为了识别更改,必须重新计算该值。因此,当您将这样的侦听器添加到可观察值时,它不再是惰性求值,而是急切求值。

当值不再有效时,会通知无效侦听器。但是,这并不意味着该值已更改。这允许我们在不知道值的情况下触发失效事件。该值将在访问之前进行评估。

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

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

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

于 2016-02-19T18:18:31.333 回答