我试图了解Java FX中事件处理的不同方面。我已经通读了 Oracle 材料,但我仍然有点困惑,想知道是否有人可以简洁地解释一些不同选项的差异和关键用途。
首先,从我所看到的情况来看,有事件处理程序和事件过滤器,然后是方便的方法。那么处理程序和过滤器之间的主要区别是什么,为什么我会使用一个而不是另一个。此外,使用 addEventHandler(...) 而不是使用便利方法添加事件处理程序有什么好处?从我自己的测试中,我相信使用 addEventHandler(...) 您可以将多个事件处理程序附加到给定的控件,而使用 setOnEvent-type(...) 只允许附加一个事件处理程序,因为它每次设置时都会覆盖属性。还有其他区别吗?
然后是 ChangeListener 和 InvalidListener 的主题 - 我认为 ChangeListener 是一种事件处理程序,专门设计用于侦听(属性)的更改事件是否正确?除了JavaFX属性和绑定的Oracle页面之外,我似乎找不到很多使用ChangeListener的示例 - 有人知道一个好的指南吗?此外,简单来说,我什么时候会在 ChangeListener 和 InvalidListener 之间进行选择?
最后,有时是否可以通过传统的 EventHandler 或 ChangeListener 模拟相同的事件处理程序 - 例如,可以使用 ActionEvent 处理按钮单击——有没有办法通过 ChangeListener 来做到这一点?我可以看到理论上您可以向 onActionProperty 添加一个更改侦听器,但我认为单击按钮时不会调用它,而是如果 setOnAction 实际上更改了附加的事件处理程序?
那么处理程序和过滤器之间的主要区别是什么,为什么我 会使用一个而不是另一个。
关键区别在于每个发生的时间。事件筛选器在事件捕获阶段调用,该阶段发生在事件冒泡阶段(调用事件处理程序)之前。因此,您可以在通知处理程序之前筛选(使用)不希望处理的事件。大多数情况下,您只想使用处理程序,而不用担心过滤器。但是,在某些情况下,您需要筛选事件。例如,假设一个游戏,其中鼠标处理程序移动游戏角色。如果用户打开游戏内菜单,您不希望他能够单击"穿过"菜单进入游戏并在菜单打开时移动角色。一种可能的方法是筛选这些鼠标事件,并在它们到达注册处理程序的节点之前使用它们。当然,您可以将鼠标处理程序附加到不同的内容而不是整个场景,但这超出了示例中强调的重点。
顾名思义,便利处理程序是为了方便而存在的。它减少了样板代码并允许简单的API。根据JavaFX文档,它们在事件链中被称为最后一个。因此,如果您只有一种感兴趣的事件类型,则应首选这些方法。
总而言之,按此顺序使用便利性和事件处理程序,如果需要对事件调度进行更多控制,还可以添加过滤器。
此外,简单来说,我什么时候会在 ChangeListener 和 InvalidListener?
当值实际上已更改时,将通知更改侦听器。为了识别更改,必须重新计算该值。因此,当您将这样的侦听器添加到可观察值时,它不再是懒惰的计算,而是急切地计算。
当值不再有效时,将通知失效侦听器。但是,这并不意味着值已更改。这允许我们在不知道值的情况下触发失效事件。该值将在访问之前进行评估。
因此,简单来说,如果您需要知道可观察对象的新值,请使用 ChangeListener,否则请使用 InvalidListener。
我可以看到,理论上您可以向 onActionProperty,但我认为这不会在以下情况下被调用 按钮被单击,但如果 setOnAction 实际上更改了 附加的事件处理程序?
是的,你是对的。要处理按钮单击,您需要使用 setOnAction()
。 ChangeListener
与事件处理无关。