Frames | No Frames |
1: /* MetalToolTipUI.java 2: Copyright (C) 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.plaf.metal; 40: 41: import java.awt.Color; 42: import java.awt.Dimension; 43: import java.awt.Font; 44: import java.awt.FontMetrics; 45: import java.awt.Graphics; 46: import java.awt.event.InputEvent; 47: import java.awt.event.KeyEvent; 48: 49: import javax.swing.AbstractButton; 50: import javax.swing.JComponent; 51: import javax.swing.JMenuItem; 52: import javax.swing.JToolTip; 53: import javax.swing.KeyStroke; 54: import javax.swing.UIManager; 55: import javax.swing.border.Border; 56: import javax.swing.plaf.ComponentUI; 57: import javax.swing.plaf.UIResource; 58: import javax.swing.plaf.basic.BasicToolTipUI; 59: 60: /** 61: * A UI delegate for the {@link JToolTip} component. 62: */ 63: public class MetalToolTipUI 64: extends BasicToolTipUI 65: { 66: /** 67: * The amount of space between the tool tip text and the accelerator 68: * description (if visible). 69: */ 70: public static final int padSpaceBetweenStrings = 12; 71: 72: /** The shared UI instance. */ 73: private static MetalToolTipUI instance; 74: 75: /** A flag controlling the visibility of the accelerator (if there is one). */ 76: private boolean isAcceleratorHidden; 77: 78: /** A string representing the accelerator key for the component. */ 79: private String acceleratorString; 80: 81: /** 82: * The delimiter for the accelerator string. 83: */ 84: private String acceleratorDelimiter; 85: 86: /** The font for the accelerator string. */ 87: private Font acceleratorFont; 88: 89: /** The color for the accelerator string. */ 90: private Color acceleratorForeground; 91: 92: /** The active border. */ 93: private Border activeBorder; 94: 95: /** The inactive border. */ 96: private Border inactiveBorder; 97: 98: /** 99: * Constructs a new instance of <code>MetalToolTipUI</code>. 100: */ 101: public MetalToolTipUI() 102: { 103: super(); 104: activeBorder = UIManager.getBorder("ToolTip.border"); 105: inactiveBorder = UIManager.getBorder("ToolTip.borderInactive"); 106: isAcceleratorHidden = UIManager.getBoolean("ToolTip.hideAccelerator"); 107: acceleratorFont = UIManager.getFont("MenuItem.acceleratorFont"); 108: acceleratorForeground = UIManager.getColor("MenuItem.acceleratorForeground"); 109: acceleratorDelimiter = UIManager.getString("MenuItem.acceleratorDelimiter"); 110: } 111: 112: /** 113: * Returns a shared instance of the <code>MetalToolTipUI</code> class. 114: * Although this UI delegate does maintain state information, there is never 115: * more than one tool tip visible, so it is OK to use a shared instance. 116: * 117: * @param component the component (a {@link JToolTip}). 118: * 119: * @return A shared instance of the <code>MetalToolTipUI</code> class. 120: */ 121: public static ComponentUI createUI(JComponent component) 122: { 123: if (instance == null) 124: instance = new MetalToolTipUI(); 125: return instance; 126: } 127: 128: /** 129: * Returns a string representing the accelerator key (if there is one) for 130: * the component that the tool tip belongs to. 131: * 132: * @return A string representing the accelerator key. 133: */ 134: public String getAcceleratorString() 135: { 136: return acceleratorString; 137: } 138: 139: /** 140: * Installs the UI for the specified component (a {@link JToolTip}). 141: * 142: * @param c the {@link JToolTip} component. 143: */ 144: public void installUI(JComponent c) 145: { 146: super.installUI(c); 147: Border existingBorder = c.getBorder(); 148: if (existingBorder == null || existingBorder instanceof UIResource) 149: { 150: if (c.isEnabled()) 151: c.setBorder(activeBorder); 152: else 153: c.setBorder(inactiveBorder); 154: } 155: } 156: 157: /** 158: * Clears the defaults set in {@link #installUI(JComponent)}. 159: * 160: * @param c the component. 161: */ 162: public void uninstallUI(JComponent c) 163: { 164: super.uninstallUI(c); 165: if (c.getBorder() instanceof UIResource) 166: c.setBorder(null); 167: } 168: 169: /** 170: * Returns <code>true</code> if the accelerator string is hidden, and 171: * <code>false</code> otherwise. This setting is controlled by the 172: * <code>ToolTip.hideAccelerator</code> entry in the UI defaults table. 173: * 174: * @return A boolean. 175: */ 176: protected boolean isAcceleratorHidden() 177: { 178: return isAcceleratorHidden; 179: } 180: 181: /** 182: * Returns the preferred size for the {@link JToolTip} component. 183: * 184: * @param c the component (a {@link JToolTip}). 185: * 186: * @return The preferred size. 187: */ 188: public Dimension getPreferredSize(JComponent c) 189: { 190: Dimension d = super.getPreferredSize(c); 191: String acc = getAcceleratorString(); 192: if (acc != null && ! acc.equals("")) 193: { 194: FontMetrics fm = c.getFontMetrics(c.getFont()); 195: d.width += fm.stringWidth(acc); 196: } 197: return d; 198: } 199: 200: /** 201: * Paints the tool tip. 202: * 203: * @param g the graphics context. 204: * @param c the {@link JToolTip} component. 205: */ 206: public void paint(Graphics g, JComponent c) 207: { 208: super.paint(g, c); 209: // Somehow paint accelerator. Keep care for possible HTML rendering. 210: } 211: 212: /** 213: * Returns a string representing the accelerator for the component, or 214: * <code>null</code> if the component has no accelerator. 215: * 216: * @param c the component. 217: * 218: * @return A string representing the accelerator (possibly 219: * <code>null</code>). 220: */ 221: private String fetchAcceleratorString(JComponent c) 222: { 223: String result = null; 224: if (c instanceof JToolTip) 225: { 226: JToolTip toolTip = (JToolTip) c; 227: JComponent component = toolTip.getComponent(); 228: KeyStroke ks = null; 229: int mne = 0; 230: if (component instanceof JMenuItem) 231: { 232: JMenuItem item = (JMenuItem) component; 233: ks = item.getAccelerator(); 234: if (ks == null) 235: mne = item.getMnemonic(); 236: } 237: else if (component instanceof AbstractButton) 238: { 239: AbstractButton button = (AbstractButton) component; 240: mne = button.getMnemonic(); 241: } 242: if (mne > 0) 243: ks = KeyStroke.getKeyStroke(Character.toUpperCase((char) mne), 244: InputEvent.ALT_MASK, false); 245: if (ks != null) 246: result = acceleratorToString(ks); 247: } 248: return result; 249: } 250: 251: /** 252: * Returns a string representing an accelerator. 253: * 254: * @param accelerator the accelerator (<code>null</code> not permitted). 255: * 256: * @return A string representing an accelerator. 257: */ 258: private String acceleratorToString(KeyStroke accelerator) 259: { 260: // convert keystroke into string format 261: String modifiersText = ""; 262: int modifiers = accelerator.getModifiers(); 263: char keyChar = accelerator.getKeyChar(); 264: int keyCode = accelerator.getKeyCode(); 265: 266: if (modifiers != 0) 267: modifiersText = KeyEvent.getKeyModifiersText(modifiers) 268: + acceleratorDelimiter; 269: 270: if (keyCode == KeyEvent.VK_UNDEFINED) 271: return modifiersText + keyChar; 272: else 273: return modifiersText + KeyEvent.getKeyText(keyCode); 274: } 275: 276: }