Force a Java Tooltip to Appear

后端 未结 5 1012
慢半拍i
慢半拍i 2021-01-07 22:51

Given a JTextField (or any JComponent for that matter), how would one go about forcing that component\'s designated tooltip to appear, without any

相关标签:
5条回答
  • 2021-01-07 22:58

    The only way (besides creating your own Tooltip window) I've found is to emmulate the CTRL+F1 keystroke on focus:

    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();}
        }
    }
    

    Unfortunately, the tooltip will disappear as soon as you move your mouse (outside of the component) or after a delay (see ToolTipManager.setDismissDelay).

    0 讨论(0)
  • 2021-01-07 23:01

    It's not a ToolTip, but you can use a balloon tip: http://timmolderez.be/balloontip/doku.php

    It is showing just on call and feels better in some moments then Default ToolTip

    0 讨论(0)
  • 2021-01-07 23:07

    For me works the similar version stated above (instead of Timer I used SwingUtilities and invokeLater approach):

    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 讨论(0)
  • 2021-01-07 23:10

    You need to invoke the default Action to show the tooltip. For example to show a tooltip when a component gains focus you can add the following FocusListener to the component:

    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 );
            }
    
        }
    };
    

    Edit:

    The above code doesn't seem to work anymore. Another approach is dispatch a MouseEvent to the component:

    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();
                }
            });
        }
    }
    

    This approach will result in a slight delay before the tooltip is displayed as it simulated the mouse entering the component. For immediate display of the tooltip you can use pstanton's solution.

    0 讨论(0)
  • 2021-01-07 23:12

    You can access the ToolTipManager, set the initial delay to 0 and send it an event. Don't forget to restore the values afterwards.

    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());
    }
    
    0 讨论(0)
提交回复
热议问题