强制Java工具提示出现

时间:2011-06-24 20:32:47

标签: java tooltip

给定一个JTextField(或任何JComponent),如何在没有来自用户的任何直接输入事件的情况下强制显示该组件的指定工具提示?换句话说,为什么没有JComponent.setTooltipVisible(boolean)

5 个答案:

答案 0 :(得分:5)

除了创建自己的工具提示窗口之外,我发现的唯一方法就是在焦点上设置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),工具提示就会消失。

答案 1 :(得分:4)

您需要调用默认操作以显示工具提示。例如,要在组件获得焦点时显示工具提示,您可以将以下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的解决方案。

答案 2 :(得分:2)

对我来说,上面说的是类似的版本(而不是我使用SwingUtilities和invokeLater方法的Timer):

private void showTooltip(Component component)
{
    final ToolTipManager ttm = ToolTipManager.sharedInstance();
    final int oldDelay = ttm.getInitialDelay();
    ttm.setInitialDelay(0);
    ttm.mouseMoved(new MouseEvent(component, 0, 0, 0,
            0, 0, // X-Y of the mouse for the tool tip
            0, false));
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run() 
        {
            ttm.setInitialDelay(oldDelay);
        }
    });
}

答案 3 :(得分:0)

您可以访问ToolTipManager,将初始延迟设置为0并向其发送事件。不要忘记之后恢复价值。

private void displayToolTip()
{
    final ToolTipManager ttm = ToolTipManager.sharedInstance();
    final MouseEvent event = new MouseEvent(this, 0, 0, 0,
                                            0, 0, // X-Y of the mouse for the tool tip
                                            0, false);
    final int oldDelay = ttm.getInitialDelay();
    final String oldText = textPane.getToolTipText(event);
    textPane.setToolTipText("<html><a href='http://www.google.com'>google</a></html>!");
    ttm.setInitialDelay(0);
    ttm.setDismissDelay(1000);
    ttm.mouseMoved(event);

    new Timer().schedule(new TimerTask()
    {
        @Override
        public void run()
        {
            ttm.setInitialDelay(oldDelay);
            textPane.setToolTipText(oldText);
        }
    }, ttm.getDismissDelay());
}

答案 4 :(得分:0)

这不是ToolTip,但您可以使用气球提示: http://timmolderez.be/balloontip/doku.php

它正在通话中显示,并且在某些时刻感觉更好,然后默认ToolTip