/* * @(#)MetalToolTipUI.java 1.28 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.swing.plaf.metal; import com.sun.java.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; /** * A Metal L&F extension of BasicToolTipUI. *

* Warning: * 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 JavaBeansTM * has been added to the java.beans package. * Please see {@link java.beans.XMLEncoder}. * * @version 1.28 12/19/03 * @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; super.paint(g, c); Font font = c.getFont(); FontMetrics metrics = SwingUtilities2.getFontMetrics(c, g, font); String keyText = getAcceleratorString(tip); String tipText = tip.getTipText(); if (tipText == null) { tipText = ""; } if (! (keyText.equals(""))) { // only draw control key if there is one g.setFont(smallFont); g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); SwingUtilities2.drawString(tip, g, keyText, SwingUtilities2.stringWidth( tip, metrics, tipText) + padSpaceBetweenStrings, 2 + metrics.getAscent()); } } public Dimension getPreferredSize(JComponent c) { Dimension d = super.getPreferredSize(c); String key = getAcceleratorString((JToolTip)c); if (! (key.equals(""))) { FontMetrics fm = c.getFontMetrics(smallFont); d.width += SwingUtilities2.stringWidth(c, fm, key) + padSpaceBetweenStrings; } 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 == null) { return ""; } KeyStroke[] keys; if (comp instanceof JTabbedPane) { TabbedPaneUI ui = ( (JTabbedPane)(comp) ).getUI(); if (ui instanceof MetalTabbedPaneUI) { // if comp is instance of JTabbedPane and have 'metal' look-and-feel // detect tab the mouse is over now int rolloverTabIndex = ( (MetalTabbedPaneUI)ui ).getRolloverTabIndex(); if (rolloverTabIndex == -1) keys = new KeyStroke[0]; else { // detect mnemonic for this tab int mnemonic = ((JTabbedPane)comp).getMnemonicAt(rolloverTabIndex); if (mnemonic == -1) keys = new KeyStroke[0]; else { // and store it as mnemonic for the component KeyStroke keyStroke = KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK); keys = new KeyStroke[1]; keys[0] = keyStroke; } } } else keys = comp.getRegisteredKeyStrokes(); } else keys = comp.getRegisteredKeyStrokes(); String controlKeyStr = ""; for (int i = 0; i < keys.length; i++) { int mod = keys[i].getModifiers(); int condition = comp.getConditionForKeyStroke(keys[i]); if ( condition == JComponent.WHEN_IN_FOCUSED_WINDOW ) { controlKeyStr = KeyEvent.getKeyModifiersText(mod) + acceleratorDelimiter + KeyEvent.getKeyText(keys[i].getKeyCode()); break; } } /* Special case for menu item since they do not register a keyboard action for their mnemonics and they always use Alt */ if ( controlKeyStr.equals("") && comp instanceof JMenuItem ) { int mnemonic = ((JMenuItem) comp).getMnemonic(); if ( mnemonic != 0 ) { controlKeyStr = KeyEvent.getKeyModifiersText(KeyEvent.ALT_MASK) + acceleratorDelimiter + (char)mnemonic; } } return controlKeyStr; } }