Заставить всплывающую подсказку Java появляться - PullRequest
15 голосов
/ 25 июня 2011

Учитывая JTextField (или любое JComponent в этом отношении), как можно заставить принудительно отображаться подсказку, назначенную для этого компонента, без какого-либо события прямого ввода от пользователя? Другими словами, почему нет JComponent.setTooltipVisible(boolean)?

Ответы [ 5 ]

5 голосов
/ 06 мая 2013

Единственный способ (кроме создания собственного окна всплывающей подсказки), который я нашел, состоит в том, чтобы эмулировать нажатие клавиш 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).

4 голосов
/ 25 июня 2011

Вам нужно вызвать действие по умолчанию, чтобы показать подсказку.Например, чтобы показать всплывающую подсказку, когда компонент получает фокус, вы можете добавить к нему следующий 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 голосов
/ 01 октября 2016

У меня работает аналогичная версия, изложенная выше (вместо Timer я использовал SwingUtilities и invokeLater подход):

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);
        }
    });
}
0 голосов
/ 05 сентября 2017

Это не ToolTip, но вы можете использовать всплывающую подсказку: http://timmolderez.be/balloontip/doku.php

Он отображается только при вызове и чувствует себя лучше в некоторых моментах, чем По умолчанию ToolTip

0 голосов
/ 28 июля 2015

Вы можете получить доступ к 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());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...