001 /*
002 * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.plaf.basic;
027
028 import sun.swing.SwingUtilities2;
029 import java.awt.*;
030 import java.beans.PropertyChangeEvent;
031 import java.beans.PropertyChangeListener;
032
033 import javax.swing.*;
034 import javax.swing.BorderFactory;
035 import javax.swing.border.Border;
036 import javax.swing.plaf.ToolTipUI;
037 import javax.swing.plaf.ComponentUI;
038 import javax.swing.plaf.UIResource;
039 import javax.swing.text.View;
040
041 /**
042 * Standard tool tip L&F.
043 * <p>
044 *
045 * @version 1.50 05/05/07
046 * @author Dave Moore
047 */
048 public class BasicToolTipUI extends ToolTipUI {
049 static BasicToolTipUI sharedInstance = new BasicToolTipUI();
050 /**
051 * Global <code>PropertyChangeListener</code> that
052 * <code>createPropertyChangeListener</code> returns.
053 */
054 private static PropertyChangeListener sharedPropertyChangedListener;
055
056 private PropertyChangeListener propertyChangeListener;
057
058 public static ComponentUI createUI(JComponent c) {
059 return sharedInstance;
060 }
061
062 public BasicToolTipUI() {
063 super ();
064 }
065
066 public void installUI(JComponent c) {
067 installDefaults(c);
068 installComponents(c);
069 installListeners(c);
070 }
071
072 public void uninstallUI(JComponent c) {
073 // REMIND: this is NOT getting called
074 uninstallDefaults(c);
075 uninstallComponents(c);
076 uninstallListeners(c);
077 }
078
079 protected void installDefaults(JComponent c) {
080 LookAndFeel.installColorsAndFont(c, "ToolTip.background",
081 "ToolTip.foreground", "ToolTip.font");
082 LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);
083 componentChanged(c);
084 }
085
086 protected void uninstallDefaults(JComponent c) {
087 LookAndFeel.uninstallBorder(c);
088 }
089
090 /* Unfortunately this has to remain private until we can make API additions.
091 */
092 private void installComponents(JComponent c) {
093 BasicHTML.updateRenderer(c, ((JToolTip) c).getTipText());
094 }
095
096 /* Unfortunately this has to remain private until we can make API additions.
097 */
098 private void uninstallComponents(JComponent c) {
099 BasicHTML.updateRenderer(c, "");
100 }
101
102 protected void installListeners(JComponent c) {
103 propertyChangeListener = createPropertyChangeListener(c);
104
105 c.addPropertyChangeListener(propertyChangeListener);
106 }
107
108 protected void uninstallListeners(JComponent c) {
109 c.removePropertyChangeListener(propertyChangeListener);
110
111 propertyChangeListener = null;
112 }
113
114 /* Unfortunately this has to remain private until we can make API additions.
115 */
116 private PropertyChangeListener createPropertyChangeListener(
117 JComponent c) {
118 if (sharedPropertyChangedListener == null) {
119 sharedPropertyChangedListener = new PropertyChangeHandler();
120 }
121 return sharedPropertyChangedListener;
122 }
123
124 public void paint(Graphics g, JComponent c) {
125 Font font = c.getFont();
126 FontMetrics metrics = SwingUtilities2
127 .getFontMetrics(c, g, font);
128 Dimension size = c.getSize();
129
130 g.setColor(c.getForeground());
131 // fix for bug 4153892
132 String tipText = ((JToolTip) c).getTipText();
133 if (tipText == null) {
134 tipText = "";
135 }
136
137 Insets insets = c.getInsets();
138 Rectangle paintTextR = new Rectangle(insets.left + 3,
139 insets.top, size.width - (insets.left + insets.right)
140 - 6, size.height - (insets.top + insets.bottom));
141 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
142 if (v != null) {
143 v.paint(g, paintTextR);
144 } else {
145 g.setFont(font);
146 SwingUtilities2.drawString(c, g, tipText, paintTextR.x,
147 paintTextR.y + metrics.getAscent());
148 }
149 }
150
151 public Dimension getPreferredSize(JComponent c) {
152 Font font = c.getFont();
153 FontMetrics fm = c.getFontMetrics(font);
154 Insets insets = c.getInsets();
155
156 Dimension prefSize = new Dimension(insets.left + insets.right,
157 insets.top + insets.bottom);
158 String text = ((JToolTip) c).getTipText();
159
160 if ((text == null) || text.equals("")) {
161 text = "";
162 } else {
163 View v = (c != null) ? (View) c.getClientProperty("html")
164 : null;
165 if (v != null) {
166 prefSize.width += (int) v.getPreferredSpan(View.X_AXIS) + 6;
167 prefSize.height += (int) v
168 .getPreferredSpan(View.Y_AXIS);
169 } else {
170 prefSize.width += SwingUtilities2.stringWidth(c, fm,
171 text) + 6;
172 prefSize.height += fm.getHeight();
173 }
174 }
175 return prefSize;
176 }
177
178 public Dimension getMinimumSize(JComponent c) {
179 Dimension d = getPreferredSize(c);
180 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
181 if (v != null) {
182 d.width -= v.getPreferredSpan(View.X_AXIS)
183 - v.getMinimumSpan(View.X_AXIS);
184 }
185 return d;
186 }
187
188 public Dimension getMaximumSize(JComponent c) {
189 Dimension d = getPreferredSize(c);
190 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
191 if (v != null) {
192 d.width += v.getMaximumSpan(View.X_AXIS)
193 - v.getPreferredSpan(View.X_AXIS);
194 }
195 return d;
196 }
197
198 /**
199 * Invoked when the <code>JCompoment</code> associated with the
200 * <code>JToolTip</code> has changed, or at initialization time. This
201 * should update any state dependant upon the <code>JComponent</code>.
202 *
203 * @param c the JToolTip the JComponent has changed on.
204 */
205 private void componentChanged(JComponent c) {
206 JComponent comp = ((JToolTip) c).getComponent();
207
208 if (comp != null && !(comp.isEnabled())) {
209 // For better backward compatability, only install inactive
210 // properties if they are defined.
211 if (UIManager.getBorder("ToolTip.borderInactive") != null) {
212 LookAndFeel.installBorder(c, "ToolTip.borderInactive");
213 } else {
214 LookAndFeel.installBorder(c, "ToolTip.border");
215 }
216 if (UIManager.getColor("ToolTip.backgroundInactive") != null) {
217 LookAndFeel.installColors(c,
218 "ToolTip.backgroundInactive",
219 "ToolTip.foregroundInactive");
220 } else {
221 LookAndFeel.installColors(c, "ToolTip.background",
222 "ToolTip.foreground");
223 }
224 } else {
225 LookAndFeel.installBorder(c, "ToolTip.border");
226 LookAndFeel.installColors(c, "ToolTip.background",
227 "ToolTip.foreground");
228 }
229 }
230
231 private static class PropertyChangeHandler implements
232 PropertyChangeListener {
233 public void propertyChange(PropertyChangeEvent e) {
234 String name = e.getPropertyName();
235 if (name.equals("tiptext") || "font".equals(name)
236 || "foreground".equals(name)) {
237 // remove the old html view client property if one
238 // existed, and install a new one if the text installed
239 // into the JLabel is html source.
240 JToolTip tip = ((JToolTip) e.getSource());
241 String text = tip.getTipText();
242 BasicHTML.updateRenderer(tip, text);
243 } else if ("component".equals(name)) {
244 JToolTip tip = ((JToolTip) e.getSource());
245
246 if (tip.getUI() instanceof BasicToolTipUI) {
247 ((BasicToolTipUI) tip.getUI())
248 .componentChanged(tip);
249 }
250 }
251 }
252 }
253 }
|