强制显示 Java 工具提示

2022-09-03 02:32:35

给定一个(或与此相关的任何工具),如何强制显示该组件的指定工具提示,而无需用户的任何直接输入事件?换句话说,为什么没有?JTextFieldJComponentJComponent.setTooltipVisible(boolean)


答案 1

我发现的唯一方法(除了创建您自己的工具提示窗口)是在焦点上模拟CTRL + F1击键:

new FocusAdapter()
{
    @Override
    public void focusGained(FocusEvent e)
    {
        try
        {
            KeyEvent ke = new KeyEvent(e.getComponent(), KeyEvent.KEY_PRESSED,
                    System.currentTimeMillis(), InputEvent.CTRL_MASK,
                    KeyEvent.VK_F1, KeyEvent.CHAR_UNDEFINED);
            e.getComponent().dispatchEvent(ke);
        }
        catch (Throwable e1)
        {e1.printStackTrace();}
    }
}

遗憾的是,工具提示将在您移动鼠标(在组件外部)或延迟(请参阅)后立即消失。ToolTipManager.setDismissDelay


答案 2

您需要调用默认操作来显示工具提示。例如,若要在组件获得焦点时显示工具提示,可以将以下 FocusListener 添加到组件中:

FocusAdapter focusAdapter = new FocusAdapter()
{
    public void focusGained(FocusEvent e)
    {
        JComponent component = (JComponent)e.getSource();
        Action toolTipAction = component.getActionMap().get("postTip");

        if (toolTipAction != null)
        {
            ActionEvent postTip = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, "");
            toolTipAction.actionPerformed( postTip );
        }

    }
};

编辑:

上面的代码似乎不再有效。另一种方法是将 MouseEvent 调度到组件:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PostTipSSCCE extends JPanel
{
    public PostTipSSCCE()
    {
        FocusAdapter fa = new FocusAdapter()
        {
            public void focusGained(FocusEvent e)
            {
                JComponent component = (JComponent)e.getSource();

                MouseEvent phantom = new MouseEvent(
                    component,
                    MouseEvent.MOUSE_MOVED,
                    System.currentTimeMillis(),
                    0,
                    10,
                    10,
                    0,
                    false);

                ToolTipManager.sharedInstance().mouseMoved(phantom);
            }
        };

        JButton button = new JButton("Button");
        button.setToolTipText("button tool tip");
        button.addFocusListener( fa );
        add( button );

        JTextField textField = new JTextField(10);
        textField.setToolTipText("text field tool tip");
        textField.addFocusListener( fa );
        add( textField );

        JCheckBox checkBox =  new JCheckBox("CheckBox");
        checkBox.setToolTipText("checkbox tool tip");
        checkBox.addFocusListener( fa );
        add( checkBox );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("PostTipSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new JScrollPane(new PostTipSSCCE()) );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

此方法将导致在工具提示模拟进入组件时显示工具提示之前出现轻微延迟。要立即显示工具提示,您可以使用 pstanton 的解决方案。