簡體   English   中英

如何使工具提示對鼠標事件透明?

[英]How to make a Tooltip transparent to mouse events?

javafx.scene.Node能夠使其對鼠標事件透明,因此不會將其選為此類事件的目標:

Node.mouseTransparentProperty()
如果為true,則此節點(及其所有子節點)對鼠標事件完全透明。 選擇鼠標事件的目標時,將mouseTransparent設置為true的節點及其子樹將不予考慮。

不幸的是, javafx.scene.control.Tooltip尚未實現此功能。
有一個開放的功能請求 - 但似乎沒有很多關於該主題的活動。

我的問題是:這有什么解決方法嗎? 如何將鼠標事件的工具提示透明化以將鼠標事件路由到基礎控件?

如果有人仍在尋找解決方案。 我在javafx-8中找到了一種hacky方式(使用內部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();
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM