001: /*
002: * WbToolTipUI.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.Dimension;
015: import java.awt.Font;
016: import java.awt.FontMetrics;
017: import java.awt.Graphics;
018: import java.awt.event.InputEvent;
019: import java.awt.event.KeyEvent;
020:
021: import javax.swing.JComponent;
022: import javax.swing.JMenu;
023: import javax.swing.JMenuItem;
024: import javax.swing.JToolTip;
025: import javax.swing.KeyStroke;
026: import javax.swing.UIManager;
027: import javax.swing.plaf.ComponentUI;
028: import javax.swing.plaf.basic.BasicToolTipUI;
029: import javax.swing.plaf.metal.MetalLookAndFeel;
030:
031: import workbench.gui.actions.WbAction;
032:
033: /**
034: * A copy of Sun's original MetalToolTipUI.
035: *
036: * This UI fixes a problem with the incorrect display of shortcuts
037: * in the tooltip. If the shortcut for a menu item does not contain
038: * a modifief (e.g. when the shortcut is F5) the original tooltip will
039: * display an incorrect shortcut (e.g. Alt-e).
040: * This class fixes this bug.
041: * To enable this ToolTipUI use:
042: * <code>
043: * UIManager.put("ToolTipUI", "workbench.gui.components.WbToolTipUI");
044: * </code>
045: */
046: public class WbToolTipUI extends BasicToolTipUI {
047:
048: static WbToolTipUI sharedInstance = new WbToolTipUI();
049: private Font smallFont;
050:
051: // Refer to note in getAcceleratorString about this field.
052: private JToolTip tip;
053: public static final int padSpaceBetweenStrings = 12;
054: private String acceleratorDelimiter;
055:
056: public WbToolTipUI() {
057: super ();
058: }
059:
060: public static ComponentUI createUI(JComponent c) {
061: return sharedInstance;
062: }
063:
064: public void installUI(JComponent c) {
065: super .installUI(c);
066: tip = (JToolTip) c;
067: Font f = c.getFont();
068: if (f != null) {
069: smallFont = new Font(f.getName(), f.getStyle(),
070: f.getSize() - 2);
071: }
072: acceleratorDelimiter = UIManager
073: .getString("MenuItem.acceleratorDelimiter");
074: if (acceleratorDelimiter == null) {
075: acceleratorDelimiter = "-";
076: }
077: }
078:
079: public void uninstallUI(JComponent c) {
080: super .uninstallUI(c);
081: tip = null;
082: }
083:
084: public void paint(Graphics g, JComponent c) {
085: JToolTip tp = (JToolTip) c;
086:
087: super .paint(g, c);
088:
089: Font font = c.getFont();
090: if (smallFont == null && font != null) {
091: smallFont = new Font(font.getName(), font.getStyle(), font
092: .getSize() - 2);
093: }
094: FontMetrics metrics = g.getFontMetrics(font);
095: String keyText = getAcceleratorString(tp);
096: String tipText = tp.getTipText();
097: if (tipText == null) {
098: tipText = "";
099: }
100: if (!(keyText.equals(""))) { // only draw control key if there is one
101: g.setFont(smallFont == null ? font : smallFont);
102: g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
103: g.drawString(keyText, metrics.stringWidth(tipText)
104: + padSpaceBetweenStrings, 2 + metrics.getAscent());
105: }
106: }
107:
108: public Dimension getPreferredSize(JComponent c) {
109: Dimension d = super .getPreferredSize(c);
110:
111: String key = getAcceleratorString((JToolTip) c);
112: if (!(key.equals(""))) {
113: //FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(smallFont);
114: FontMetrics fm = c.getFontMetrics(smallFont);
115: d.width += fm.stringWidth(key) + padSpaceBetweenStrings;
116: }
117: return d;
118: }
119:
120: protected boolean isAcceleratorHidden() {
121: Boolean b = (Boolean) UIManager.get("ToolTip.hideAccelerator");
122: return b != null && b.booleanValue();
123: }
124:
125: private String getAcceleratorString(JToolTip toolTip) {
126: this .tip = toolTip;
127:
128: String retValue = getAcceleratorString();
129:
130: this .tip = null;
131: return retValue;
132: }
133:
134: public String getAcceleratorString() {
135: if (tip == null || isAcceleratorHidden()) {
136: return "";
137: }
138: JComponent comp = tip.getComponent();
139: if (comp == null) {
140: return "";
141: }
142: KeyStroke[] keys = comp.getRegisteredKeyStrokes();
143: String controlKeyStr = "";
144:
145: for (int i = 0; i < keys.length; i++) {
146: int mod = keys[i].getModifiers();
147: int condition = comp.getConditionForKeyStroke(keys[i]);
148: int key = keys[i].getKeyCode();
149:
150: if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW
151: && ((mod & InputEvent.ALT_MASK) != 0
152: || (mod & InputEvent.CTRL_MASK) != 0
153: || (mod & InputEvent.SHIFT_MASK) != 0 || (mod & InputEvent.META_MASK) != 0)) {
154: controlKeyStr = KeyEvent.getKeyModifiersText(mod)
155: + acceleratorDelimiter
156: + KeyEvent.getKeyText(keys[i].getKeyCode());
157: break;
158: }
159:
160: else if (mod == 0
161: && (key == KeyEvent.VK_F1 || key == KeyEvent.VK_F2
162: || key == KeyEvent.VK_F3
163: || key == KeyEvent.VK_F4
164: || key == KeyEvent.VK_F5
165: || key == KeyEvent.VK_F6
166: || key == KeyEvent.VK_F7
167: || key == KeyEvent.VK_F8
168: || key == KeyEvent.VK_F9
169: || key == KeyEvent.VK_F10
170: || key == KeyEvent.VK_F11 || key == KeyEvent.VK_F12)
171: && (comp instanceof JMenu || comp instanceof JMenuItem)) {
172: controlKeyStr = KeyEvent.getKeyText(keys[i]
173: .getKeyCode());
174: break;
175: }
176: }
177:
178: if (controlKeyStr.length() == 0
179: && comp instanceof WbToolbarButton) {
180: WbAction action = (WbAction) ((WbToolbarButton) comp)
181: .getAction();
182: KeyStroke key = action.getAccelerator();
183: if (key != null) {
184: controlKeyStr = KeyEvent.getKeyModifiersText(key
185: .getModifiers())
186: + acceleratorDelimiter
187: + KeyEvent.getKeyText(key.getKeyCode());
188: }
189: }
190: return controlKeyStr;
191: }
192:
193: }
|