禁止子节点在不使用同一事件的情况下收到有关事件的通知



>情况

假设您有一个包含单个复杂控件的Scene,该控件本身包含一个TextArea。复杂控件的组成方式是,当它获得焦点时,TextArea获得焦点。

ComplexControl 能够使 TextArea 不可编辑。然后,键输入可以具有比操作文本不同的语义。新的语义可以由 ComplexControl 或场景图中更高的任何节点来定义。

场景具有全局快捷键 CTRL+N,用于打开新的选项卡/视图。在 ComplexControl 的上下文中,CRTL+N 语义正在创建一个新的文本文档。

------------------------
| Scene                |
|  ------------------  |
|  | ComplexControl |  |
|  |  ------------  |  |
|  |  | TextArea |  |  |
|  |  ------------  |  |
|  ------------------  |
------------------------

目的

全局反应或由场景图中稍高的节点做出反应 键事件/键组合。任何稍低的控件都可以接管事件,因此在更特殊的上下文中,发生的事件与全局定义的相关性更高。

建议

Scene或更高的Node上设置KeyHandler。任何靠近EventDispatchChain的源/目标的EventHandler都可以使用事件。这样,KeyHandler可以防止Scene或任何更高的Node对键输入做出反应,这是用户在控件的特殊上下文中的意图。因此,在较高的地方EventFilter是不合适的。

麻烦

TextArea始终使用任何关键事件,即使这不是设计的意图。EventDispatchChain中没有更高的EventHandler被告知。

问题

  1. 怎么能强迫它从TextArea中归还事件而不消耗它,然后让它冒出EventDispatchChain
  2. 如何在不使用它的情况下阻止将事件传递到文本区域,使其甚至不知道有关事件的任何信息。

感谢傻蝇,他为我指明了道路。作为问题 2 的答案,以下是结果来源。我决定将功能放在一个中心点以供重用,并有机会使抑制条件基于。请不要责怪我的类名,这不是重点;-)

public class EventUtil {
/**
* Prevents Events of the given <b>eventTypes</b> to be passed down during the
* event capturing phase, if the <b>condition</b> is met.
* 
* @param node
*          The Node, whose descendants should not be informed about the Event
* @param eventTypes
*          The types of Events for which the prevention should be valid
* @param condition
*          The condition that must be met to prevent passing the Event down
*/
public static void preventPassDown(Node node, Supplier<Boolean> condition, EventType<?>... eventTypes) {
for (EventType<?> eventType : eventTypes) {
if (eventTypes == null) {
return;
}
node.addEventFilter(eventType, event -> {
if (condition.get()) {
event.consume();
Parent parent = node.getParent();
if (parent != null) {
Event.fireEvent(parent, event);
}
}
});
}
}
/**
* Prevents Events of the given <b>eventTypes</b> to be passed down during the
* event capturing phase.
* 
* @param node
*          The Node, whose descendants should not be informed about the Event
* @param eventTypes
*          The types of Events for which the prevention should be valid
*/
public static void preventPassDown(Node node, EventType<?>... eventTypes) {
preventPassDown(node, () -> true, eventTypes);
}

如果有人找到问题 1 的答案,请随时加入。

相关内容

  • 没有找到相关文章

最新更新