1. /*
  2. * @(#)MetalToolTipUI.java 1.24 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.metal;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.*;
  11. import javax.swing.BorderFactory;
  12. import javax.swing.border.Border;
  13. import javax.swing.plaf.*;
  14. import javax.swing.plaf.basic.BasicToolTipUI;
  15. /**
  16. * A Metal L&F extension of BasicToolTipUI.
  17. * <p>
  18. * <strong>Warning:</strong>
  19. * Serialized objects of this class will not be compatible with
  20. * future Swing releases. The current serialization support is
  21. * appropriate for short term storage or RMI between applications running
  22. * the same version of Swing. As of 1.4, support for long term storage
  23. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  24. * has been added to the <code>java.beans</code> package.
  25. * Please see {@link java.beans.XMLEncoder}.
  26. *
  27. * @version 1.24 01/23/03
  28. * @author Steve Wilson
  29. */
  30. public class MetalToolTipUI extends BasicToolTipUI {
  31. static MetalToolTipUI sharedInstance = new MetalToolTipUI();
  32. private Font smallFont;
  33. // Refer to note in getAcceleratorString about this field.
  34. private JToolTip tip;
  35. public static final int padSpaceBetweenStrings = 12;
  36. private String acceleratorDelimiter;
  37. public MetalToolTipUI() {
  38. super();
  39. }
  40. public static ComponentUI createUI(JComponent c) {
  41. return sharedInstance;
  42. }
  43. public void installUI(JComponent c) {
  44. super.installUI(c);
  45. tip = (JToolTip)c;
  46. Font f = c.getFont();
  47. smallFont = new Font( f.getName(), f.getStyle(), f.getSize() - 2 );
  48. acceleratorDelimiter = UIManager.getString( "MenuItem.acceleratorDelimiter" );
  49. if ( acceleratorDelimiter == null ) { acceleratorDelimiter = "-"; }
  50. }
  51. public void uninstallUI(JComponent c) {
  52. super.uninstallUI(c);
  53. tip = null;
  54. }
  55. public void paint(Graphics g, JComponent c) {
  56. JToolTip tip = (JToolTip)c;
  57. super.paint(g, c);
  58. Font font = c.getFont();
  59. FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
  60. String keyText = getAcceleratorString(tip);
  61. String tipText = tip.getTipText();
  62. if (tipText == null) {
  63. tipText = "";
  64. }
  65. if (! (keyText.equals(""))) { // only draw control key if there is one
  66. g.setFont(smallFont);
  67. g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
  68. g.drawString(keyText,
  69. metrics.stringWidth(tipText) + padSpaceBetweenStrings,
  70. 2 + metrics.getAscent());
  71. }
  72. }
  73. public Dimension getPreferredSize(JComponent c) {
  74. Dimension d = super.getPreferredSize(c);
  75. String key = getAcceleratorString((JToolTip)c);
  76. if (! (key.equals(""))) {
  77. FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(smallFont);
  78. d.width += fm.stringWidth(key) + padSpaceBetweenStrings;
  79. }
  80. return d;
  81. }
  82. protected boolean isAcceleratorHidden() {
  83. Boolean b = (Boolean)UIManager.get("ToolTip.hideAccelerator");
  84. return b != null && b.booleanValue();
  85. }
  86. private String getAcceleratorString(JToolTip tip) {
  87. this.tip = tip;
  88. String retValue = getAcceleratorString();
  89. this.tip = null;
  90. return retValue;
  91. }
  92. // NOTE: This requires the tip field to be set before this is invoked.
  93. // As MetalToolTipUI is shared between all JToolTips the tip field is
  94. // set appropriately before this is invoked. Unfortunately this means
  95. // that subclasses that randomly invoke this method will see varying
  96. // results. If this becomes an issue, MetalToolTipUI should no longer be
  97. // shared.
  98. public String getAcceleratorString() {
  99. if (tip == null || isAcceleratorHidden()) {
  100. return "";
  101. }
  102. JComponent comp = tip.getComponent();
  103. if (comp == null) {
  104. return "";
  105. }
  106. KeyStroke[] keys =comp.getRegisteredKeyStrokes();
  107. String controlKeyStr = "";
  108. for (int i = 0; i < keys.length; i++) {
  109. int mod = keys[i].getModifiers();
  110. int condition = comp.getConditionForKeyStroke(keys[i]);
  111. if ( condition == JComponent.WHEN_IN_FOCUSED_WINDOW &&
  112. ( (mod & InputEvent.ALT_MASK) != 0 || (mod & InputEvent.CTRL_MASK) != 0 ||
  113. (mod & InputEvent.SHIFT_MASK) != 0 || (mod & InputEvent.META_MASK) != 0 ) )
  114. {
  115. controlKeyStr = KeyEvent.getKeyModifiersText(mod) +
  116. acceleratorDelimiter +
  117. KeyEvent.getKeyText(keys[i].getKeyCode());
  118. break;
  119. }
  120. }
  121. /* Special case for menu item since they do not register a
  122. keyboard action for their mnemonics and they always use Alt */
  123. if ( controlKeyStr.equals("") && comp instanceof JMenuItem )
  124. {
  125. int mnemonic = ((JMenuItem) comp).getMnemonic();
  126. if ( mnemonic != 0 )
  127. {
  128. controlKeyStr =
  129. KeyEvent.getKeyModifiersText(KeyEvent.ALT_MASK) +
  130. acceleratorDelimiter + (char)mnemonic;
  131. }
  132. }
  133. return controlKeyStr;
  134. }
  135. }