blob: d5b45d206a88a63edd21e55666a8e236f93a83c9 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.swing.plaf.basic;
27
28import sun.swing.SwingUtilities2;
29import java.awt.*;
30import java.beans.PropertyChangeEvent;
31import java.beans.PropertyChangeListener;
32
33import javax.swing.*;
34import javax.swing.BorderFactory;
35import javax.swing.border.Border;
36import javax.swing.plaf.ToolTipUI;
37import javax.swing.plaf.ComponentUI;
38import javax.swing.plaf.UIResource;
39import javax.swing.text.View;
40
41
42/**
43 * Standard tool tip L&F.
44 * <p>
45 *
46 * @author Dave Moore
47 */
48public class BasicToolTipUI extends ToolTipUI
49{
50 static BasicToolTipUI sharedInstance = new BasicToolTipUI();
51 /**
52 * Global <code>PropertyChangeListener</code> that
53 * <code>createPropertyChangeListener</code> returns.
54 */
55 private static PropertyChangeListener sharedPropertyChangedListener;
56
57 private PropertyChangeListener propertyChangeListener;
58
59 public static ComponentUI createUI(JComponent c) {
60 return sharedInstance;
61 }
62
63 public BasicToolTipUI() {
64 super();
65 }
66
67 public void installUI(JComponent c) {
68 installDefaults(c);
69 installComponents(c);
70 installListeners(c);
71 }
72
73 public void uninstallUI(JComponent c) {
74 // REMIND: this is NOT getting called
75 uninstallDefaults(c);
76 uninstallComponents(c);
77 uninstallListeners(c);
78 }
79
80 protected void installDefaults(JComponent c){
81 LookAndFeel.installColorsAndFont(c, "ToolTip.background",
82 "ToolTip.foreground",
83 "ToolTip.font");
84 LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);
85 componentChanged(c);
86 }
87
88 protected void uninstallDefaults(JComponent c){
89 LookAndFeel.uninstallBorder(c);
90 }
91
92 /* Unfortunately this has to remain private until we can make API additions.
93 */
94 private void installComponents(JComponent c){
95 BasicHTML.updateRenderer(c, ((JToolTip)c).getTipText());
96 }
97
98 /* Unfortunately this has to remain private until we can make API additions.
99 */
100 private void uninstallComponents(JComponent c){
101 BasicHTML.updateRenderer(c, "");
102 }
103
104 protected void installListeners(JComponent c) {
105 propertyChangeListener = createPropertyChangeListener(c);
106
107 c.addPropertyChangeListener(propertyChangeListener);
108 }
109
110 protected void uninstallListeners(JComponent c) {
111 c.removePropertyChangeListener(propertyChangeListener);
112
113 propertyChangeListener = null;
114 }
115
116 /* Unfortunately this has to remain private until we can make API additions.
117 */
118 private PropertyChangeListener createPropertyChangeListener(JComponent c) {
119 if (sharedPropertyChangedListener == null) {
120 sharedPropertyChangedListener = new PropertyChangeHandler();
121 }
122 return sharedPropertyChangedListener;
123 }
124
125 public void paint(Graphics g, JComponent c) {
126 Font font = c.getFont();
127 FontMetrics metrics = SwingUtilities2.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(
139 insets.left + 3,
140 insets.top,
141 size.width - (insets.left + insets.right) - 6,
142 size.height - (insets.top + insets.bottom));
143 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
144 if (v != null) {
145 v.paint(g, paintTextR);
146 } else {
147 g.setFont(font);
148 SwingUtilities2.drawString(c, g, tipText, paintTextR.x,
149 paintTextR.y + metrics.getAscent());
150 }
151 }
152
153 public Dimension getPreferredSize(JComponent c) {
154 Font font = c.getFont();
155 FontMetrics fm = c.getFontMetrics(font);
156 Insets insets = c.getInsets();
157
158 Dimension prefSize = new Dimension(insets.left+insets.right,
159 insets.top+insets.bottom);
160 String text = ((JToolTip)c).getTipText();
161
162 if ((text == null) || text.equals("")) {
163 text = "";
164 }
165 else {
166 View v = (c != null) ? (View) c.getClientProperty("html") : null;
167 if (v != null) {
168 prefSize.width += (int) v.getPreferredSpan(View.X_AXIS) + 6;
169 prefSize.height += (int) v.getPreferredSpan(View.Y_AXIS);
170 } else {
171 prefSize.width += SwingUtilities2.stringWidth(c,fm,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) - v.getMinimumSpan(View.X_AXIS);
183 }
184 return d;
185 }
186
187 public Dimension getMaximumSize(JComponent c) {
188 Dimension d = getPreferredSize(c);
189 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
190 if (v != null) {
191 d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
192 }
193 return d;
194 }
195
196 /**
197 * Invoked when the <code>JCompoment</code> associated with the
198 * <code>JToolTip</code> has changed, or at initialization time. This
199 * should update any state dependant upon the <code>JComponent</code>.
200 *
201 * @param c the JToolTip the JComponent has changed on.
202 */
203 private void componentChanged(JComponent c) {
204 JComponent comp = ((JToolTip)c).getComponent();
205
206 if (comp != null && !(comp.isEnabled())) {
207 // For better backward compatability, only install inactive
208 // properties if they are defined.
209 if (UIManager.getBorder("ToolTip.borderInactive") != null) {
210 LookAndFeel.installBorder(c, "ToolTip.borderInactive");
211 }
212 else {
213 LookAndFeel.installBorder(c, "ToolTip.border");
214 }
215 if (UIManager.getColor("ToolTip.backgroundInactive") != null) {
216 LookAndFeel.installColors(c,"ToolTip.backgroundInactive",
217 "ToolTip.foregroundInactive");
218 }
219 else {
220 LookAndFeel.installColors(c,"ToolTip.background",
221 "ToolTip.foreground");
222 }
223 } else {
224 LookAndFeel.installBorder(c, "ToolTip.border");
225 LookAndFeel.installColors(c, "ToolTip.background",
226 "ToolTip.foreground");
227 }
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 }
244 else if ("component".equals(name)) {
245 JToolTip tip = ((JToolTip) e.getSource());
246
247 if (tip.getUI() instanceof BasicToolTipUI) {
248 ((BasicToolTipUI)tip.getUI()).componentChanged(tip);
249 }
250 }
251 }
252 }
253}