javafx.scene.Node
能够使其对鼠标事件透明,因此不会被选为此类事件的目标:
Node.mouseTransparentProperty()
如果为true,则此节点(及其所有子节点)对鼠标事件完全透明。选择鼠标事件的目标时,将mouseTransparent设置为true的节点及其子树不会被考虑在内。
不幸的是,javafx.scene.control.Tooltip
尚未实现此功能
有一个开放的功能request - 但在这个主题上似乎没有很多活动。
我的问题是:这有什么解决方法吗?如何将鼠标事件的工具提示透明化以将鼠标事件路由到基础控件?
答案 0 :(得分:1)
如果有人仍在寻找解决方案。我在javafx-8中发现了一种骇人听闻的方法(使用内部API!)。它可能是在Javafx-8 +中进行了修补,因此从可维护性的角度来看,这不是一个好选择,但至少可以做到:
public static boolean correctNativeMouseEvent(MouseEvent event, Scene exclude)
{
Scene targetScene = getTargetScreen(event, exclude);
if(targetScene != null)
{
PickResultChooser chooser = new PickResultChooser();
targetScene.getRoot().impl_pickNode(new PickRay(event.getScreenX() - targetScene.getWindow().getX() - targetScene.getX(),
event.getScreenY() - targetScene.getWindow().getY() - targetScene.getY(),
1, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), chooser);
PickResult res = chooser.toPickResult();
if(res != null)
{
Point2D pos = res.getIntersectedNode().localToScene(res.getIntersectedPoint().getX(), res.getIntersectedPoint().getY());
MouseEvent newEvent = new MouseEvent(null, null, event.getEventType(), pos.getX(), pos.getY(),
event.getScreenX(), event.getScreenY(),
event.getButton(), event.getClickCount(),
event.isShiftDown(), event.isControlDown(), event.isAltDown(), event.isMetaDown(),
event.isPrimaryButtonDown(), event.isMiddleButtonDown(), event.isSecondaryButtonDown(),
event.isSynthesized(), event.isPopupTrigger(), event.isStillSincePress(), res);
targetScene.impl_processMouseEvent(newEvent);
return true;
}
}
return false;
}
static Scene getTargetScreen(MouseEvent event, Scene exclude)
{
double x = event.getScreenX();
double y = event.getScreenY();
double sx, sy, sw, sh;
Iterator<Window> itr = Window.impl_getWindows();
if(itr.hasNext())
{
for(Window w = itr.next(); itr.hasNext(); w = itr.next())
{
sx = w.getX();
sy = w.getY();
sw = w.getWidth();
sh = w.getHeight();
if(sx < x && x < sx + sw
&& sy < y && y < sy + sh
&& w.getScene() != exclude)
return w.getScene();
}
}
return null;
}
创建工具提示后,只需添加以下内容:
Tooltip tp = new Tooltip();
// use filter to catch before anything can be consumed
tp.addEventFilter(MouseEvent.ANY, E -> {
// now correct the event
correctNativeMouseEvent(E, tp.getScene());
// although it is optionally, I would recommend to just consume the event anyways
E.consume();
};