JavaFX 2事件派发到底层节点

问题描述:

有没有正确的方法来解决两个兄弟窗格之间的事件传播问题?JavaFX 2事件派发到底层节点

例如我们有StackPane里面有2个窗格。

StackPane p = new StackPane(); 
Region p1 = new Region(); 
Region p2 = new Region(); 
p.getChildren().addAll(p1, p2); 

p2在这个例子中捕获鼠标事件和p1不能对它做出反应,即使事件没有被消耗。

如果事件没有被p2消耗,是否有正确的方法将事件传播给p1?

setMouseTransparent无法解决我的问题,因为我需要这两个子元素都对鼠标作出反应。

感谢您的建议。

+0

请参阅https://stackoverflow.com/a/45016452/3992939 – c0der 2017-07-10 15:51:11

我的问题部分解决。也许我不太正确地提出问题。 我写图像编辑器之类的应用程序,并在导航栏,网格,选择工具等等的堆叠面板上使用工具层窗格,并且需要该层的子项可以处理鼠标和窗格本身对鼠标事件是透明的。

问题是通过覆盖pickNode解决的,而不是在公共API中,但它的工作。 也许帮助别人。

protected Node impl_pickNodeLocal(double localX, double localY) { 
    if (containsBounds(localX, localY)) { 
     ObservableList<Node> children = getChildren(); 
     for (int i = children.size()-1; i >= 0; i--) { 
      Node picked = children.get(i).impl_pickNode(localX, localY); 
      if (picked != null) return picked; 
     } 
     // hack to make pane itself transparent for mouse 
     // if (contains(localX, localY)) return this; 
    } 
    return null; 
} 
+0

这不起作用了。 impl_ *'方法已被弃用,“有效私有”和最终。 – piegames 2017-08-29 14:19:57

默认情况下,事件只会向上传播并终止于根。有几种方法可以解决您的问题。

  1. 创建您自己的事件实例。向两个触发共享事件实例的区域添加一个事件处理程序。将您希望在区域间通用的任何事件处理代码添加到共享实例。这是我从你给出的描述中采取的方法。
  2. 抓住根的所有事件,而不是让他们死,创建一个全球事件注册,每个人都可以注册。
  3. 在第一个区域创建一个事件处理程序,捕获事件并在第二个区域重新分派它们(使用buildEventDispatchChain.dispatchEvent)。然后在另一边做同样的事情。

正好赶上在事件处理程序的事件,并触发其上的其他组件:

top.addEventHandler(EventType.ROOT, event -> bottom.fireEvent(event)); 

,您仍然可以在顶部组件添加鼠标监听器,它工作正常。如果底层组件在事件中使用更多花哨的东西,则可能需要克隆并调整它。这也适用于两个以上的孩子。