我已经谷歌搜索了一段时间,我发现基本上,一些网页上说没有太大的差异。除了一些要点:
EventFilter
在EventHandler
EventFilter
对event.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
在这种情况下,将执行boath EventFilter
,但EventHandler
不会执行。正确?
还有其他事要知道吗?在哪些情况下我应该优先考虑其中一个?我有时会一起使用它们来解决一些问题吗?
谢谢!
答案 0 :(得分:7)
无论何时发生事件,都会遵循确定场景图中哪个节点应处理事件的过程。该过程采取以下步骤:
目标选择,假设您的场景包含带有圆圈的窗格。如果单击该圆圈,则该圆圈将成为事件目标。
路线构建接下来,JavaFX创建一条路线(或事件分配链)。在我们的示例中,链看起来像stage -> scene -> pane -> circle
事件捕获该事件通过链上的每个事件过滤器传递。只要其中一个过滤器调用consume()
,链就会停止,该节点将成为目标。如果没有过滤器调用consume()
,则链的末端(圆圈)仍然是目标。
事件冒泡接下来,事件再次通过链进行推送,但这一次是从事件目标到阶段。因此,如果窗格事件过滤器名为consume()
,则会命中以下事件处理程序:pane -> scene -> stage
因此,不同之处不仅在于这些处理程序被激活时,而且事件过滤器可以阻止子节点接收事件。
答案 1 :(得分:3)
据我所知,JavaFX EventFilter 对于单个节点可以是一个或多个,对于许多节点可以是单个节点。 EventFilter 使您能够在事件捕获阶段期间处理事件,但事件处理程序在事件冒泡阶段期间处理事件。
所以EventFilter在EventHandler之前执行。
javafx event handler (http://javafxtuts.com/javafx-event-handler/)
JavaFX EventFilter (http://javafxtuts.com/javafx-event-filter/)
答案 2 :(得分:2)
我不完全理解你的问题,但我在oracle docs上发现了这个问题:
过滤器和处理程序之间的主要区别在于每个过程都被执行。
答案 3 :(得分:0)
当您注册任何事件(例如(button.setOnAction(new Clicker()))时,此处的开始/第一个事件来源将是舞台,而目标将是按钮。现在stage将该事件委托给Scene,场景将委托给根节点等等。最后按钮将获得事件。这里Clicker是一个将使用该事件的处理程序。如果我们想在处理之前跟踪该事件,那么"事件过滤器"进入了画面。在这里我们可以跟踪该事件。跟踪一旦我们消费该事件,那么这将不会进一步委托。如果我们不消耗,这将委托给直接/直接子节点。跟踪之后如果你想发射一些其他事件,那么我们可以调用fireEvent(...)方法。 更多访问oracle文档 a link!
答案 4 :(得分:0)
应该有一个"逻辑"差异。
当出于某种原因,我们希望阻止管理处理程序代码中计划的事件并停止其传播时,应使用过滤器。
事实上,正如你正确指出的那样,标记为"消费"该事件意味着不得启动事件处理程序。
我们可以阅读Oracle文档(http://docs.oracle.com/javafx/2/events/filters.htm):
事件过滤器通常用于事件的分支节点 调度链,在事件捕获阶段被调用 事件处理。使用过滤器执行操作,例如覆盖 事件响应或阻止事件到达目的地。
答案 5 :(得分:0)
事件过滤器是一个事件处理程序 - 设置为在事件到达节点之前处理它。您无法创建EventFilter。
node.addEventFilter(EventType, eventFilter)
- 其中evenFilter是一个EventHandler对象!
你可以看看这个,你可以使用它来阻止/“覆盖”已在节点中定义的某些固有输入控件,例如TextArea:How to consume a TAB/Enter KeyPressed on the TextArea, and replace with focustraversal or enter key without using internal API?