java JavaFX:EventHandler 和 EventFilter 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25740103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:35:27  来源:igfitidea点击:

JavaFX: what is the difference between EventHandler and EventFilter?

javaevents

提问by bog

I've been googling for a while and I found that basicly, some web pages says there are no big differences. Except for some points:

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

  1. EventFilteris executed before EventHandler
  2. EventFilteris not sensible to event.Consume();Let me see If I've understood it: Lets say I have:

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

  1. EventFilter之前执行 EventHandler
  2. EventFilterevent.Consume();让我看看如果我理解它是不明智的:假设我有:

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

Let's say they are both "linked" to an MouseEvent.MOUSE_CLICKED; then, EventFilter's code will be the first to be executed!?

假设它们都“链接”到一个MouseEvent.MOUSE_CLICKED; 那么,EventFilter的代码将首先被执行!?

Let's say, now, I have:

让我们说,现在,我有:

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

In this case, boath EventFilters will be executed but the EventHandlerwill not. Right?

在这种情况下,EventFilter将会执行boath s 但EventHandler不会执行。对?

Are there any other things to know? Are there situations where I should prefere one or other? should I sometimes use them together in order to solve some problems?

还有什么要知道的吗?在某些情况下,我应该选择其中一种还是另一种?我有时应该将它们一起使用以解决一些问题吗?

Thank you!

谢谢!

回答by sirolf2009

Whenever an event happens, it follows a process to determine which node in the scene graph should handle the event. The process takes these steps:

每当事件发生时,它都会遵循一个过程来确定场景图中的哪个节点应该处理该事件。该过程采取以下步骤:

  • Target selection
  • Route construction
  • Event capturing <- filters are triggered here
  • Event bubbling <- handlers are triggered here
  • 目标选择
  • 路线建设
  • 事件捕获 <- 过滤器在此处触发
  • 事件冒泡 <- 处理程序在此处触发

Target SelectionSay that your scene contains a pane with a circle. If you click on the circle, the circle becomes the event target.

目标选择假设您的场景包含一个带圆圈的窗​​格。如果单击圆圈,圆圈将成为事件目标。

Route ConstructionNext, JavaFX creates a route (or an event dispatch chain). In our example the chain would look like stage -> scene -> pane -> circle

路由构建接下来,JavaFX 创建一个路由(或一个事件调度链)。在我们的例子中,链看起来像stage -> scene -> pane -> circle

Event CapturingThe event gets carried through every event filter on the chain. As soon as one of the filters calls consume(), the chain stops and that node becomes the target. If no filter calls consume()the end of the chain (the circle) remains the target.

事件捕获事件通过链上的每个事件过滤器进行。一旦其中一个过滤器调用consume(),链就会停止并且该节点成为目标。如果没有过滤器调用consume()链的末端(圆圈)仍然是目标。

Event BubblingNext, the event get pushed through the chain again, but this time from the event target to the stage. So if the pane event filter called consume(), the following event handlers will be hit: pane -> scene -> stage

事件冒泡接下来,事件再次通过链推送,但这次是从事件目标到舞台。因此,如果窗格事件过滤器调用consume(),将命中以下事件处理程序:pane -> scene -> stage

So the difference is not only when these handlers get activated, but also that event filters can prevent child nodes from receiving events.

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

回答by Ganesh

As I know JavaFX EventFiltercan be one or many for a single node and can be single for many nodes. EventFilterenable you to handle an event during the event capturing phasebut the event handler handle events during the event bubbling phase.

据我所知,JavaFX EventFilter可以是单个节点的一个或多个,也可以是多个节点的单个。 EventFilter使您能够在事件捕获阶段处理事件,而事件处理程序在事件冒泡阶段处理事件。

So EventFilter is executed before the EventHandler.

所以EventFilter在EventHandler之前执行。

javafx event handler(http://javafxtuts.com/javafx-event-handler/)

javafx 事件处理程序http://javafxtuts.com/javafx-event-handler/

JavaFX EventFilter(http://javafxtuts.com/javafx-event-filter/)

JavaFX 事件过滤器http://javafxtuts.com/javafx-event-filter/

java docs

Java 文档

回答by i3anaan

I do not fully understand your question, but I found this on the oracle docs:

我不完全理解你的问题,但我在 oracle 文档中找到了这个:

The primary difference between a filter and a handler is when each one is executed.

过滤器和处理程序之间的主要区别在于它们的执行时间。

https://docs.oracle.com/javafx/2/events/processing.htm

https://docs.oracle.com/javafx/2/events/processing.htm

回答by Rakesh Kumar MooN

When you are registering any event like(button.setOnAction(new Clicker())) here starting/first Source of event will be stage and Target will be button. Now stage will delegate that event to Scene and scene will delegate to root Node and so on.finally button will get event. Here Clicker is a handler that will consume that event. If we want to track that event before handling then "Event Filter" comes into the picture. here we can track that event. After tracking once we consume that event then this will not delegate further. If we are not consuming, this will delegate to direct/immediate child node. After tracking If you want to fire some other event then we can call fireEvent(...) method. for more visit oracle documentation a link!

当您在此处注册任何事件时,例如 (button.setOnAction(new Clicker())) 开始/第一个事件源将是舞台,目标将是按钮。现在舞台将该事件委托给场景,场景将委托给根节点等等。最后按钮将获得事件。这里的 Clicker 是一个将使用该事件的处理程序。如果我们想在处理之前跟踪该事件,那么“事件过滤器”就会出现。在这里,我们可以跟踪该事件。在我们消费该事件后进行跟踪后,将不会进一步委托。如果我们不消费,这将委托给直接/立即子节点。跟踪之后如果你想触发一些其他事件,那么我们可以调用 fireEvent(...) 方法。有关更多访问 oracle 文档 的链接

回答by Alessandro

There should be a "logical" difference.
The filter should be used when, for some reason, we want to prevent the management of the event planned in the handler's code and to stop his propagation.
In fact, as you have rightly pointed out, marking as "consumed" the event means that the event handler must not be launched. It the Oracle docs (http://docs.oracle.com/javafx/2/events/filters.htm) we can read:

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

Event filters are typically used on a branch node of the event dispatch chain and are called during the event capturing phase of event handling. Use a filter to perform actions such as overriding an event response or blocking an event from reaching its destination.

事件过滤器通常用在事件调度链的一个分支节点上,在事件处理的事件捕获阶段被调用。使用过滤器执行操作,例如覆盖事件响应或阻止事件到达其目的地。

回答by Lealo

An event filter is an event handler - being set to handle an event before it gets to the node. You cannot create an EventFilter.

事件过滤器是一个事件处理程序 - 被设置为在事件到达节点之前处理事件。您不能创建 EventFilter。

node.addEventFilter(EventType, eventFilter)- Where evenFilter is a EventHandler object!

node.addEventFilter(EventType, eventFilter)- 其中 evenFilter 是一个 EventHandler 对象!

You can take a look at this where you can use it to block/"override" certain inherent input controls already defined in nodes such as TextArea: How to consume a TAB/Enter KeyPressed on the TextArea, and replace with focustraversal or enter key without using internal API?

您可以看看这个,您可以使用它来阻止/“覆盖”某些已在节点中定义的固有输入控件,例如 TextArea:如何在TextArea上使用 TAB/Enter KeyPressed,并替换为 focustraversal 或 enter key without使用内部API?