JDK-4449310 : Accelerator not displayed in HTML tool tip (Metal L&F)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2001-04-23
  • Updated: 2005-10-21
  • Resolved: 2005-10-21
Related Reports
Duplicate :  
Description
Name: yyT116575			Date: 04/23/2001


java version "1.3.1-rc1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-rc1-b21)
Java HotSpot(TM) Client VM (build 1.3.1-rc1-b21, mixed mode)

Accelerator is never shown in tool tip!

The bug results in the accelerator text in a tool tip positioned arbitrarily. 
The example shows one buttons where the accelerator text is overlaying 
the tool tip text and another one, where the accelerator text is not shown
at all.

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

public class ToolTipBug extends JFrame {
  ToolTipBug() {
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    JPanel  p   = new JPanel();
        
    JButton b1  = new JButton("Correct ToolTip");
    b1.setMnemonic(KeyEvent.VK_C);
    b1.setToolTipText("This one displays a correct tool tip");
    p.add(b1);
        
    JButton b2  = new JButton("Wrong ToolTip 1");
    b2.setMnemonic(KeyEvent.VK_1);
    b2.setToolTipText("<html><font size=+2>This one displays the accelerator text overlayed on the tool tip text");
    p.add(b2);
        
    JButton b3  = new JButton("Wrong ToolTip 2");
    b3.setMnemonic(KeyEvent.VK_2);
    b3.setToolTipText("<html><font size=-1>This one displays<br>no accelerator<br>text at all");
    p.add(b3);
        
    getContentPane().add(p);
        
    pack();
    setVisible(true);
  }
    
  public static void main(String[] args) {
    new ToolTipBug();
  }
}

I pointed out the very line in JDK source that is wrong: 
javax.swing.plaf.metal.MetalToolTipUI.java, line # 74 (in paint() method)
and I included a better version.

I figured out that the code to calculate the position of the accelerator text
is broken: See MetalToolTipUI.paint(Graphics g, JComponent c):
   g.drawString(keyText, metrics.stringWidth(tipText) + padSpaceBetweenStrings,
2 + metrics.getAscent());
It tries to calculate the position by using metric on the tool tip text. This
must fail for html text.

A better solution is to always draw the accelerator text in the bottom right
corner (though the margin constants are somewhat arbitrary):
   g.drawString(keyText, c.getWidth() - 2 - metrics.stringWidth(keyText),
c.getHeight() - 2 - metrics.getDescent());
Where metrics is changed to mean metrics of 'smallFont'.
(Review ID: 121029) 
======================================================================

Comments
EVALUATION This has already been fixed by 5047379. First, we no longer show the mnemonic in the tooltip text. If there is an accelerator, however, we will show it correctly. The calculations have been corrected for when HTML is used.
21-10-2005

EVALUATION Name: apR10133 Date: 08/20/2001 As mentioned in description the accelerator's text position calculation is broken because it always calculate the width of the string as the plain text width (including the tags). ###@###.### ======================================================================
25-09-2004

SUGGESTED FIX Name: apR10133 Date: 08/20/2001 ------- MetalToolTipUI.java ------- *** /tmp/dqraOFj Mon Aug 20 16:10:22 2001 --- MetalToolTipUI.java Mon Aug 20 16:07:00 2001 *************** *** 81,89 **** if (! (keyText.equals(""))) { // only draw control key if there is one g.setFont(smallFont); g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); ! g.drawString(keyText, ! metrics.stringWidth(tipText) + padSpaceBetweenStrings, ! 2 + metrics.getAscent()); } } --- 81,90 ---- if (! (keyText.equals(""))) { // only draw control key if there is one g.setFont(smallFont); g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); ! FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(smallFont); ! g.drawString(keyText, ! c.getWidth() - 2 - fm.stringWidth(keyText), ! c.getHeight()/2 + fm.getAscent()/2); } } If the accelerator text shouldn't be centered for html tooltips please use the: g.drawString(keyText, c.getWidth() - 2 - fm.stringWidth(keyText), c.getHeight() - 2 - fm.getDescent()); ###@###.### ======================================================================
25-09-2004