001 /* BasicToolTipUI.java --
002 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038
039 package javax.swing.plaf.basic;
040
041 import java.awt.Color;
042 import java.awt.Dimension;
043 import java.awt.Font;
044 import java.awt.FontMetrics;
045 import java.awt.Graphics;
046 import java.awt.Insets;
047 import java.awt.Rectangle;
048 import java.beans.PropertyChangeEvent;
049 import java.beans.PropertyChangeListener;
050
051 import javax.swing.JComponent;
052 import javax.swing.JToolTip;
053 import javax.swing.LookAndFeel;
054 import javax.swing.plaf.ComponentUI;
055 import javax.swing.plaf.ToolTipUI;
056 import javax.swing.text.View;
057
058 /**
059 * This is the Basic Look and Feel UI class for JToolTip.
060 */
061 public class BasicToolTipUI extends ToolTipUI
062 {
063
064 /**
065 * Receives notification when a property of the JToolTip changes.
066 * This updates the HTML renderer if appropriate.
067 */
068 private class PropertyChangeHandler
069 implements PropertyChangeListener
070 {
071
072 public void propertyChange(PropertyChangeEvent e)
073 {
074 String prop = e.getPropertyName();
075 if (prop.equals("tiptext") || prop.equals("font")
076 || prop.equals("foreground"))
077 {
078 JToolTip tip = (JToolTip) e.getSource();
079 String text = tip.getTipText();
080 BasicHTML.updateRenderer(tip, text);
081 }
082 }
083
084 }
085
086 /** The shared instance of BasicToolTipUI used for all ToolTips. */
087 private static BasicToolTipUI shared;
088
089 /** The tooltip's text */
090 private String text;
091
092 /**
093 * Handles property changes.
094 */
095 private PropertyChangeListener propertyChangeHandler;
096
097 /**
098 * Creates a new BasicToolTipUI object.
099 */
100 public BasicToolTipUI()
101 {
102 super();
103 }
104
105 /**
106 * This method creates a new BasicToolTip UI for the given
107 * JComponent.
108 *
109 * @param c The JComponent to create a UI for.
110 *
111 * @return A BasicToolTipUI that can be used by the given JComponent.
112 */
113 public static ComponentUI createUI(JComponent c)
114 {
115 if (shared == null)
116 shared = new BasicToolTipUI();
117 return shared;
118 }
119
120 /**
121 * This method returns the msximum size of the given JComponent.
122 *
123 * @param c The JComponent to find a maximum size for.
124 *
125 * @return The maximum size.
126 */
127 public Dimension getMaximumSize(JComponent c)
128 {
129 Dimension d = getPreferredSize(c);
130 View view = (View) c.getClientProperty(BasicHTML.propertyKey);
131 if (view != null)
132 d.width += view.getMaximumSpan(View.X_AXIS)
133 - view.getPreferredSpan(View.X_AXIS);
134 return d;
135 }
136
137 /**
138 * This method returns the minimum size of the given JComponent.
139 *
140 * @param c The JComponent to find a minimum size for.
141 *
142 * @return The minimum size.
143 */
144 public Dimension getMinimumSize(JComponent c)
145 {
146 Dimension d = getPreferredSize(c);
147 View view = (View) c.getClientProperty(BasicHTML.propertyKey);
148 if (view != null)
149 d.width -= view.getPreferredSpan(View.X_AXIS)
150 - view.getMinimumSpan(View.X_AXIS);
151 return d;
152 }
153
154 /**
155 * This method returns the preferred size of the given JComponent.
156 *
157 * @param c The JComponent to find a preferred size for.
158 *
159 * @return The preferred size.
160 */
161 public Dimension getPreferredSize(JComponent c)
162 {
163 JToolTip tip = (JToolTip) c;
164 String str = tip.getTipText();
165 FontMetrics fm = c.getFontMetrics(c.getFont());
166 Insets i = c.getInsets();
167 Dimension d = new Dimension(i.left + i.right, i.top + i.bottom);
168 if (str != null && ! str.equals(""))
169 {
170 View view = (View) c.getClientProperty(BasicHTML.propertyKey);
171 if (view != null)
172 {
173 d.width += (int) view.getPreferredSpan(View.X_AXIS);
174 d.height += (int) view.getPreferredSpan(View.Y_AXIS);
175 }
176 else
177 {
178 d.width += fm.stringWidth(str) + 6;
179 d.height += fm.getHeight();
180 }
181 }
182 return d;
183 }
184
185 /**
186 * This method installs the defaults for the given JComponent.
187 *
188 * @param c The JComponent to install defaults for.
189 */
190 protected void installDefaults(JComponent c)
191 {
192 LookAndFeel.installColorsAndFont(c, "ToolTip.background",
193 "ToolTip.foreground", "ToolTip.font");
194 LookAndFeel.installBorder(c, "ToolTip.border");
195 }
196
197 /**
198 * This method installs the listeners for the given JComponent.
199 *
200 * @param c The JComponent to install listeners for.
201 */
202 protected void installListeners(JComponent c)
203 {
204 propertyChangeHandler = new PropertyChangeHandler();
205 c.addPropertyChangeListener(propertyChangeHandler);
206 }
207
208 /**
209 * This method installs the UI for the given JComponent.
210 *
211 * @param c The JComponent to install the UI for.
212 */
213 public void installUI(JComponent c)
214 {
215 c.setOpaque(true);
216 installDefaults(c);
217 BasicHTML.updateRenderer(c, ((JToolTip) c).getTipText());
218 installListeners(c);
219 }
220
221 /**
222 * This method paints the given JComponent with the given Graphics object.
223 *
224 * @param g The Graphics object to paint with.
225 * @param c The JComponent to paint.
226 */
227 public void paint(Graphics g, JComponent c)
228 {
229 JToolTip tip = (JToolTip) c;
230
231 String text = tip.getTipText();
232 Font font = c.getFont();
233 FontMetrics fm = c.getFontMetrics(font);
234 int ascent = fm.getAscent();
235 Insets i = c.getInsets();
236 Dimension size = c.getSize();
237 Rectangle paintR = new Rectangle(i.left, i.top,
238 size.width - i.left - i.right,
239 size.height - i.top - i.bottom);
240 Color saved = g.getColor();
241 Font oldFont = g.getFont();
242 g.setColor(Color.BLACK);
243
244 View view = (View) c.getClientProperty(BasicHTML.propertyKey);
245 if (view != null)
246 view.paint(g, paintR);
247 else
248 g.drawString(text, paintR.x + 3, paintR.y + ascent);
249
250 g.setFont(oldFont);
251 g.setColor(saved);
252 }
253
254 /**
255 * This method uninstalls the defaults for the given JComponent.
256 *
257 * @param c The JComponent to uninstall defaults for.
258 */
259 protected void uninstallDefaults(JComponent c)
260 {
261 c.setForeground(null);
262 c.setBackground(null);
263 c.setFont(null);
264 c.setBorder(null);
265 }
266
267 /**
268 * This method uninstalls listeners for the given JComponent.
269 *
270 * @param c The JComponent to uninstall listeners for.
271 */
272 protected void uninstallListeners(JComponent c)
273 {
274 if (propertyChangeHandler != null)
275 {
276 c.removePropertyChangeListener(propertyChangeHandler);
277 propertyChangeHandler = null;
278 }
279 }
280
281 /**
282 * This method uninstalls the UI for the given JComponent.
283 *
284 * @param c The JComponent to uninstall.
285 */
286 public void uninstallUI(JComponent c)
287 {
288 uninstallDefaults(c);
289 BasicHTML.updateRenderer(c, "");
290 uninstallListeners(c);
291 }
292 }