1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
/* * @(#)MetalToolTipUI.java 1.31 05/11/30 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.swing.plaf.metal; import sun.swing.SwingUtilities2; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.BorderFactory; import javax.swing.border.Border; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicToolTipUI; import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.View; /** * A Metal L&F extension of BasicToolTipUI. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @version 1.31 11/30/05 * @author Steve Wilson */ public class MetalToolTipUI extends BasicToolTipUI { static MetalToolTipUI sharedInstance = new MetalToolTipUI(); private Font smallFont; // Refer to note in getAcceleratorString about this field. private JToolTip tip; public static final int padSpaceBetweenStrings = 12; private String acceleratorDelimiter; public MetalToolTipUI() { super(); } public static ComponentUI createUI(JComponent c) { return sharedInstance; } public void installUI(JComponent c) { super.installUI(c); tip = (JToolTip)c; Font f = c.getFont(); smallFont = new Font( f.getName(), f.getStyle(), f.getSize() - 2 ); acceleratorDelimiter = UIManager.getString( "MenuItem.acceleratorDelimiter" ); if ( acceleratorDelimiter == null ) { acceleratorDelimiter = "-"; } } public void uninstallUI(JComponent c) { super.uninstallUI(c); tip = null; } public void paint(Graphics g, JComponent c) { JToolTip tip = (JToolTip)c; Font font = c.getFont(); FontMetrics metrics = SwingUtilities2.getFontMetrics(c, g, font); Dimension size = c.getSize(); int accelBL; g.setColor(c.getForeground()); // fix for bug 4153892 String tipText = tip.getTipText(); if (tipText == null) { tipText = ""; } String accelString = getAcceleratorString(tip); FontMetrics accelMetrics = SwingUtilities2.getFontMetrics(c, g, smallFont); int accelSpacing = calcAccelSpacing(c, accelMetrics, accelString); Insets insets = tip.getInsets(); Rectangle paintTextR = new Rectangle( insets.left + 3, insets.top, size.width - (insets.left + insets.right) - 6 - accelSpacing, size.height - (insets.top + insets.bottom)); View v = (View) c.getClientProperty(BasicHTML.propertyKey); if (v != null) { v.paint(g, paintTextR); accelBL = BasicHTML.getHTMLBaseline(v, paintTextR.width, paintTextR.height); } else { g.setFont(font); SwingUtilities2.drawString(tip, g, tipText, paintTextR.x, paintTextR.y + metrics.getAscent()); accelBL = metrics.getAscent(); } if (!accelString.equals("")) { g.setFont(smallFont); g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); SwingUtilities2.drawString(tip, g, accelString, tip.getWidth() - 1 - insets.right - accelSpacing + padSpaceBetweenStrings - 3, paintTextR.y + accelBL); } } private int calcAccelSpacing(JComponent c, FontMetrics fm, String accel) { return accel.equals("") ? 0 : padSpaceBetweenStrings + SwingUtilities2.stringWidth(c, fm, accel); } public Dimension getPreferredSize(JComponent c) { Dimension d = super.getPreferredSize(c); String key = getAcceleratorString((JToolTip)c); if (!(key.equals(""))) { d.width += calcAccelSpacing(c, c.getFontMetrics(smallFont), key); } return d; } protected boolean isAcceleratorHidden() { Boolean b = (Boolean)UIManager.get("ToolTip.hideAccelerator"); return b != null && b.booleanValue(); } private String getAcceleratorString(JToolTip tip) { this.tip = tip; String retValue = getAcceleratorString(); this.tip = null; return retValue; } // NOTE: This requires the tip field to be set before this is invoked. // As MetalToolTipUI is shared between all JToolTips the tip field is // set appropriately before this is invoked. Unfortunately this means // that subclasses that randomly invoke this method will see varying // results. If this becomes an issue, MetalToolTipUI should no longer be // shared. public String getAcceleratorString() { if (tip == null || isAcceleratorHidden()) { return ""; } JComponent comp = tip.getComponent(); if (!(comp instanceof AbstractButton)) { return ""; } KeyStroke[] keys = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).keys(); if (keys == null) { return ""; } String controlKeyStr = ""; for (int i = 0; i < keys.length; i++) { int mod = keys[i].getModifiers(); controlKeyStr = KeyEvent.getKeyModifiersText(mod) + acceleratorDelimiter + KeyEvent.getKeyText(keys[i].getKeyCode()); break; } return controlKeyStr; } }