假设您有一个Scene
,其中包含一个复杂的控件,它本身包含TextArea
。复合控制以某种方式组成,当它获得焦点时,TextArea
获得焦点。
ComplexControl能够使TextArea不可编辑。然后,键输入可以具有除操作文本之外的另一种语义。新的语义可以由ComplexControl或任何节点定义,在场景图中更高。
场景具有全局快捷键CTRL + N,用于打开新的选项卡/视图。在ComplexControl的上下文中,CRTL + N语义正在创建一个新的文本文档。
------------------------
| Scene |
| ------------------ |
| | ComplexControl | |
| | ------------ | |
| | | TextArea | | |
| | ------------ | |
| ------------------ |
------------------------
在KeyEvents / KeyCombinations的场景图中全局或由某个节点稍微反应。任何较低的控制都可以接管事件,因此在更特殊的上下文中,发生的事件与全局定义具有更多相关性。
将KeyHandler
设置为Scene
或更高Node
。靠近EventHandler
的来源/目标的任何EventDispatchChain
都可以使用此事件。KeyHandler
可以阻止Scene
或任何更高的Node
对键输入作出反应,这是用户在控件的特殊上下文中的意图。因此,较高位置的EventFilter
不合适。
TextArea
总是消耗任何关键事件,即使这不是设计的意图。 <{1}}中的EventHandler
更高通知。
EventDispatchChain
发回事件而不消耗它,然后让它冒出TextArea
?答案 0 :(得分:1)
Thanx到sillyfly,谁给我指路。作为对问题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的答案,请随时加入。