001/* BasicToolTipUI.java -- 002 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.swing.plaf.basic; 040 041import java.awt.Color; 042import java.awt.Dimension; 043import java.awt.Font; 044import java.awt.FontMetrics; 045import java.awt.Graphics; 046import java.awt.Insets; 047import java.awt.Rectangle; 048import java.beans.PropertyChangeEvent; 049import java.beans.PropertyChangeListener; 050 051import javax.swing.JComponent; 052import javax.swing.JToolTip; 053import javax.swing.LookAndFeel; 054import javax.swing.plaf.ComponentUI; 055import javax.swing.plaf.ToolTipUI; 056import javax.swing.text.View; 057 058/** 059 * This is the Basic Look and Feel UI class for JToolTip. 060 */ 061public 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}