001 /* BasicRadioButtonUI.java
002 Copyright (C) 2002, 2004, 2006, 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.Graphics;
045 import java.awt.Insets;
046 import java.awt.Rectangle;
047
048 import javax.swing.AbstractButton;
049 import javax.swing.ButtonModel;
050 import javax.swing.Icon;
051 import javax.swing.JComponent;
052 import javax.swing.SwingUtilities;
053 import javax.swing.UIManager;
054 import javax.swing.plaf.ComponentUI;
055 import javax.swing.text.View;
056
057 /**
058 * The BasicLookAndFeel UI implementation for
059 * {@link javax.swing.JRadioButton}s.
060 */
061 public class BasicRadioButtonUI extends BasicToggleButtonUI
062 {
063 /**
064 * The default icon for JRadioButtons. The default icon displays the usual
065 * RadioButton and is sensible to the selection state of the button,
066 * and can be used both as normal icon as well as selectedIcon.
067 */
068 protected Icon icon;
069
070 /**
071 * Creates and returns a new instance of <code>BasicRadioButtonUI</code>.
072 *
073 * @return a new instance of <code>BasicRadioButtonUI</code>
074 */
075 public static ComponentUI createUI(final JComponent c)
076 {
077 return new BasicRadioButtonUI();
078 }
079
080 /**
081 * Creates a new instance of <code>BasicButtonUI</code>.
082 */
083 public BasicRadioButtonUI()
084 {
085 // nothing to do
086 }
087
088 /**
089 * Installs defaults from the Look & Feel table on the specified
090 * button.
091 *
092 * @param b the button on which to install the defaults
093 */
094 protected void installDefaults(AbstractButton b)
095 {
096 super.installDefaults(b);
097 icon = UIManager.getIcon(getPropertyPrefix() + "icon");
098 }
099
100 /**
101 * Returns the prefix used for UIDefaults properties. This is
102 * <code>RadioButton</code> in this case.
103 *
104 * @return the prefix used for UIDefaults properties
105 */
106 protected String getPropertyPrefix()
107 {
108 return "RadioButton.";
109 }
110
111 /**
112 * Returns the default icon for JRadioButtons.
113 * The default icon displays the usual
114 * RadioButton and is sensible to the selection state of the button,
115 * and can be used both as normal icon as well as selectedIcon.
116 *
117 * @return the default icon for JRadioButtons
118 */
119 public Icon getDefaultIcon()
120 {
121 return icon;
122 }
123
124 /**
125 * Paints the RadioButton.
126 *
127 * @param g the Graphics context to paint with
128 * @param c the button to paint
129 */
130 public void paint(Graphics g, JComponent c)
131 {
132 AbstractButton b = (AbstractButton) c;
133 Dimension size = c.getSize();
134 Insets i = b.getInsets();
135 textR.x = 0;
136 textR.y = 0;
137 textR.width = 0;
138 textR.height = 0;
139 iconR.x = 0;
140 iconR.y = 0;
141 iconR.width = 0;
142 iconR.height = 0;
143 viewR.x = i.left;
144 viewR.y = i.right;
145 viewR.width = size.width - i.left - i.right;
146 viewR.height = size.height - i.top - i.bottom;
147
148 Font f = c.getFont();
149
150 g.setFont(f);
151
152 // This is the icon that we use for layout.
153 Icon icon = b.getIcon();
154 if (icon == null)
155 icon = getDefaultIcon();
156
157 // Figure out the correct icon.
158 Icon currentIcon = getCurrentIcon(b);
159
160 // Do the layout.
161 String text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
162 b.getText(), currentIcon == null ? getDefaultIcon() : currentIcon,
163 b.getVerticalAlignment(), b.getHorizontalAlignment(),
164 b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
165 viewR, iconR, textR, b.getIconTextGap());
166
167 // .. and paint it.
168 if (currentIcon != null)
169 currentIcon.paintIcon(c, g, iconR.x, iconR.y);
170
171 // Paint text and focus indicator.
172 if (text != null)
173 {
174 // Maybe render HTML in the radio button.
175 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
176 if (v != null)
177 v.paint(g, textR);
178 else
179 paintText(g, b, textR, text);
180
181 // Paint focus indicator if necessary.
182 if (b.hasFocus() && b.isFocusPainted()
183 && textR.width > 0 && textR.height > 0)
184 paintFocus(g, textR, size);
185 }
186 }
187
188 /**
189 * Determines the icon to be displayed for the specified radio button.
190 *
191 * @param b the radio button
192 *
193 * @return the icon
194 */
195 private Icon getCurrentIcon(AbstractButton b)
196 {
197 ButtonModel m = b.getModel();
198 Icon currentIcon = b.getIcon();
199
200 if (currentIcon == null)
201 {
202 currentIcon = getDefaultIcon();
203 }
204 else
205 {
206 if (! m.isEnabled())
207 {
208 if (m.isSelected())
209 currentIcon = b.getDisabledSelectedIcon();
210 else
211 currentIcon = b.getDisabledIcon();
212 }
213 else if (m.isPressed() && m.isArmed())
214 {
215 currentIcon = b.getPressedIcon();
216 if (currentIcon == null)
217 currentIcon = b.getSelectedIcon();
218 }
219 else if (m.isSelected())
220 {
221 if (b.isRolloverEnabled() && m.isRollover())
222 {
223 currentIcon = b.getRolloverSelectedIcon();
224 if (currentIcon == null)
225 currentIcon = b.getSelectedIcon();
226 }
227 else
228 currentIcon = b.getSelectedIcon();
229 }
230 else if (b.isRolloverEnabled() && m.isRollover())
231 {
232 currentIcon = b.getRolloverIcon();
233 }
234 if (currentIcon == null)
235 currentIcon = b.getIcon();
236 }
237 return currentIcon;
238 }
239
240 public Dimension getPreferredSize(JComponent c)
241 {
242 // This is basically the same code as in
243 // BasicGraphicsUtils.getPreferredButtonSize() but takes the default icon
244 // property into account. JRadioButton and subclasses always have an icon:
245 // the check box. If the user explicitly changes it with setIcon() that
246 // one will be used for layout calculations and painting instead.
247 // The other icon properties are ignored.
248 AbstractButton b = (AbstractButton) c;
249
250 Insets insets = b.getInsets();
251
252 String text = b.getText();
253 Icon i = b.getIcon();
254 if (i == null)
255 i = getDefaultIcon();
256
257 textR.x = 0;
258 textR.y = 0;
259 textR.width = 0;
260 textR.height = 0;
261 iconR.x = 0;
262 iconR.y = 0;
263 iconR.width = 0;
264 iconR.height = 0;
265 viewR.x = 0;
266 viewR.y = 0;
267 viewR.width = Short.MAX_VALUE;
268 viewR.height = Short.MAX_VALUE;
269
270 SwingUtilities.layoutCompoundLabel(b, // for the component orientation
271 b.getFontMetrics(b.getFont()),
272 text, i, b.getVerticalAlignment(),
273 b.getHorizontalAlignment(),
274 b.getVerticalTextPosition(),
275 b.getHorizontalTextPosition(),
276 viewR, iconR, textR,
277 text == null ? 0 : b.getIconTextGap());
278
279 Rectangle r = SwingUtilities.computeUnion(textR.x, textR.y, textR.width,
280 textR.height, iconR);
281
282 return new Dimension(insets.left + r.width + insets.right,
283 insets.top + r.height + insets.bottom);
284 }
285
286 /**
287 * Paints the focus indicator for JRadioButtons.
288 *
289 * @param g the graphics context
290 * @param tr the rectangle for the text label
291 * @param size the size of the <code>JRadioButton</code> component.
292 */
293 protected void paintFocus(Graphics g, Rectangle tr, Dimension size)
294 {
295 Color focusColor = UIManager.getColor(getPropertyPrefix() + ".focus");
296 Color saved = g.getColor();
297 g.setColor(focusColor);
298 g.drawRect(tr.x, tr.y, tr.width, tr.height);
299 g.setColor(saved);
300 }
301 }