You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当FocusableWindowState为false时Swing Tooltip失效的合规解决方法

问题:无焦点悬浮Overlay中Swing Tooltip无法正常显示

我开发了一款针对全屏游戏的悬浮Overlay应用,给JFrame设置了以下属性:

this.setFocusableWindowState(false);
this.setFocusable(false);
this.setAlwaysOnTop(true);

但JFrame上按钮的Tooltip始终无法显示。查文档得知,JComponent.setTooltipText(String text)会向tooltipManager.sharedInstance注册组件,但仅当组件具备焦点绑定时才会生效(出自ToolTipManager.registerComponent方法文档)。

我试过把JFrame的setFocusableWindowState(true)改回来,但会导致窗口闪烁,没法稳定保持在游戏窗口上层。

目前我通过反射调用私有字段和方法实现了Tooltip显示(代码里的"tooltip magic"部分),但希望找到基于Swing内置函数的合规实现方式,不想用这种hack手段。之前也尝试过自行实现Tooltip系统,但引出了一堆其他问题。

以下是最小复现示例:

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {

    public static void main(String args[]) {
        JFrame frame = new JFrame("Tooltip test");
        frame.setVisible(true);
        frame.setFocusable(false);
        frame.setFocusableWindowState(false);
        frame.setAlwaysOnTop(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300,300);
        JButton button = new JButton("Press");
        String tooltip = "tooltip value";

        //notWorkingTooltip(button, tooltip);
        workingTooltip(button, tooltip);

        frame.getContentPane().add(button);
    }

    private static void notWorkingTooltip(JButton button, String tooltip) {
        button.setToolTipText(tooltip);
    }

    private static void workingTooltip(JButton button, String tooltip) {
        button.setToolTipText(tooltip);
        button.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseEntered(MouseEvent e) {
                UIManager.put("ToolTipManager.enableToolTipMode", "test");
                try {
                    Method method = ToolTipManager.class.getDeclaredMethod("showTipWindow");
                    Field field = ToolTipManager.class.getDeclaredField("mouseEvent");
                    field.setAccessible(true);
                    field.set(ToolTipManager.sharedInstance(), e);
                    method.setAccessible(true);
                    method.invoke(ToolTipManager.sharedInstance());
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException |
                         NoSuchFieldException ex) {
                    ex.printStackTrace();
                }
                ToolTipManager.sharedInstance().mouseMoved(e);
                ToolTipManager.sharedInstance().mouseEntered(e);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                UIManager.put("ToolTipManager.enableToolTipMode", "activeApplication");
            }
        });
    }
}

内容的提问来源于stack exchange,提问作者Morph21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:17:02