JavaFX:EventHandler和EventFilter有什么区别?

27

我已经谷歌搜索了一段时间,基本上有些网页说没有太大的区别。除了一些要点:

  1. EventFilterEventHandler之前执行
  2. EventFilterevent.Consume();不敏感。 让我看看我的理解是否正确: 假设我有:

    Button b = new Button("Test"); b.addEventHandler(.....){...}; b.addEventFilter(......){...};

假设它们都与一个MouseEvent.MOUSE_CLICKED相关联,那么EventFilter的代码将首先被执行!?

现在假设我有:

Button b= new Button("Test");
b.addEventHandler(.....);
b.addEventFilter(......){
  //some code
  event.consume();
}; // First filter
b.addEventFilter(......){
  //some other code
  event.consume();
}; // Second filter

在这种情况下,两个 EventFilter 都会被执行,但是 EventHandler 不会被执行。对吗?

还有其他需要知道的事情吗?是否存在应该更喜欢其中一个的情况?我是否应该有时候将它们一起使用以解决某些问题?

谢谢!

6个回答

33

每当事件发生时,都会按照一定的流程决定场景图中哪个节点应该处理事件。这个过程包括以下步骤:

  • 目标选择
  • 路径构建
  • 事件捕获 <- 过滤器在此阶段触发
  • 事件冒泡 <- 处理器在此阶段触发

目标选择 假设你的场景中包含一个带圆的面板。如果你点击圆,那么圆就成为了事件目标。

路径构建 接下来,JavaFX会创建一条路线(或一个事件分配链)。在我们的例子中,链应该是这样的:stage -> scene -> pane -> circle

事件捕获 事件通过链上的每个事件过滤器传递。只要其中一个过滤器调用consume()方法,链就会停止,并且该节点将变成事件目标。如果没有任何过滤器调用consume()方法,则链的末端(即圆)仍然是事件目标。

事件冒泡 接下来,事件再次从事件目标向舞台推送,但是这一次是反向的。因此,如果面板事件过滤器调用了consume()方法,则将触发以下事件处理器:pane -> scene -> stage

因此,区别不仅在于何时激活这些处理程序,还在于事件过滤器可以阻止子节点接收事件。


4
据我所知,JavaFX的EventFilter可以是单个节点的一个或多个,也可以是多个节点的一个。 EventFilter使您能够在事件捕获阶段期间处理事件,但是事件处理程序在事件冒泡阶段期间处理事件。
因此,在EventHandler之前执行EventFilter。
java docs

2

0

应该有一个“逻辑”差别。
当某些原因需要防止处理程序代码中计划的事件管理并停止其传播时,应使用过滤器。
事实上,正如您所指出的那样,将事件标记为“已消耗”意味着不应启动事件处理程序。 在Oracle文档(http://docs.oracle.com/javafx/2/events/filters.htm)中,我们可以读到:

事件过滤器通常用于事件分派链的分支节点,并在事件处理的捕获阶段调用。使用过滤器执行诸如覆盖事件响应或阻止事件到达其目的地等操作。


0

当您注册任何事件,例如(button.setOnAction(new Clicker())),这里事件的起始/第一个源将是舞台(stage),目标将是按钮(button)。现在,舞台将委托该事件给场景(Scene),场景将委托给根节点(root Node),以此类推,最终按钮将获得事件。这里Clicker是一个处理程序(handler),它将消耗该事件。如果我们想在处理之前跟踪该事件,则"事件过滤器"就会出现。在这里,我们可以跟踪该事件。跟踪一次后,如果我们消耗了该事件,则不会再委托。如果我们没有消耗,那么它将委托给直接/立即子节点。在跟踪后,如果您想触发其他事件,则可以调用fireEvent(...)方法。 欲了解更多,请访问Oracle文档a link


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接