History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/plaf/basic/BasicLabelUI.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/plaf/basic/BasicLabelUI.java+486−0
@@ -0,0 +1,486 @@
1/*
2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.swing.plaf.basic;
27
28import sun.swing.SwingUtilities2;
29import sun.swing.DefaultLookup;
30import sun.swing.UIAction;
31import sun.awt.AppContext;
32
33import javax.swing.*;
34import javax.swing.plaf.*;
35import javax.swing.text.View;
36
37import java.awt.event.ActionEvent;
38import java.awt.event.ActionListener;
39import java.awt.event.KeyEvent;
40import java.awt.Component;
41import java.awt.Container;
42import java.awt.Dimension;
43import java.awt.Rectangle;
44import java.awt.Insets;
45import java.awt.Color;
46import java.awt.Graphics;
47import java.awt.Font;
48import java.awt.FontMetrics;
49import java.beans.PropertyChangeEvent;
50import java.beans.PropertyChangeListener;
51
52/**
53 * A Windows L&F implementation of LabelUI. This implementation
54 * is completely static, i.e. there's only one UIView implementation
55 * that's shared by all JLabel objects.
56 *
57 * @author Hans Muller
58 */
59public class BasicLabelUI extends LabelUI implements PropertyChangeListener
60{
61 /**
62 * The default <code>BasicLabelUI</code> instance. This field might
63 * not be used. To change the default instance use a subclass which
64 * overrides the <code>createUI</code> method, and place that class
65 * name in defaults table under the key "LabelUI".
66 */
67 protected static BasicLabelUI labelUI = new BasicLabelUI();
68 private static final Object BASIC_LABEL_UI_KEY = new Object();
69
70 private Rectangle paintIconR = new Rectangle();
71 private Rectangle paintTextR = new Rectangle();
72
73 static void loadActionMap(LazyActionMap map) {
74 map.put(new Actions(Actions.PRESS));
75 map.put(new Actions(Actions.RELEASE));
76 }
77
78 /**
79 * Forwards the call to SwingUtilities.layoutCompoundLabel().
80 * This method is here so that a subclass could do Label specific
81 * layout and to shorten the method name a little.
82 *
83 * @see SwingUtilities#layoutCompoundLabel
84 */
85 protected String layoutCL(
86 JLabel label,
87 FontMetrics fontMetrics,
88 String text,
89 Icon icon,
90 Rectangle viewR,
91 Rectangle iconR,
92 Rectangle textR)
93 {
94 return SwingUtilities.layoutCompoundLabel(
95 (JComponent) label,
96 fontMetrics,
97 text,
98 icon,
99 label.getVerticalAlignment(),
100 label.getHorizontalAlignment(),
101 label.getVerticalTextPosition(),
102 label.getHorizontalTextPosition(),
103 viewR,
104 iconR,
105 textR,
106 label.getIconTextGap());
107 }
108
109 /**
110 * Paint clippedText at textX, textY with the labels foreground color.
111 *
112 * @see #paint
113 * @see #paintDisabledText
114 */
115 protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY)
116 {
117 int mnemIndex = l.getDisplayedMnemonicIndex();
118 g.setColor(l.getForeground());
119 SwingUtilities2.drawStringUnderlineCharAt(l, g, s, mnemIndex,
120 textX, textY);
121 }
122
123
124 /**
125 * Paint clippedText at textX, textY with background.lighter() and then
126 * shifted down and to the right by one pixel with background.darker().
127 *
128 * @see #paint
129 * @see #paintEnabledText
130 */
131 protected void paintDisabledText(JLabel l, Graphics g, String s, int textX, int textY)
132 {
133 int accChar = l.getDisplayedMnemonicIndex();
134 Color background = l.getBackground();
135 g.setColor(background.brighter());
136 SwingUtilities2.drawStringUnderlineCharAt(l, g, s, accChar,
137 textX + 1, textY + 1);
138 g.setColor(background.darker());
139 SwingUtilities2.drawStringUnderlineCharAt(l, g, s, accChar,
140 textX, textY);
141 }
142
143 /**
144 * Paints the label text with the foreground color, if the label is opaque
145 * then paints the entire background with the background color. The Label
146 * text is drawn by {@link #paintEnabledText} or {@link #paintDisabledText}.
147 * The locations of the label parts are computed by {@link #layoutCL}.
148 *
149 * @see #paintEnabledText
150 * @see #paintDisabledText
151 * @see #layoutCL
152 */
153 public void paint(Graphics g, JComponent c)
154 {
155 JLabel label = (JLabel)c;
156 String text = label.getText();
157 Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
158
159 if ((icon == null) && (text == null)) {
160 return;
161 }
162
163 FontMetrics fm = SwingUtilities2.getFontMetrics(label, g);
164 String clippedText = layout(label, fm, c.getWidth(), c.getHeight());
165
166 if (icon != null) {
167 icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
168 }
169
170 if (text != null) {
171 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
172 if (v != null) {
173 v.paint(g, paintTextR);
174 } else {
175 int textX = paintTextR.x;
176 int textY = paintTextR.y + fm.getAscent();
177
178 if (label.isEnabled()) {
179 paintEnabledText(label, g, clippedText, textX, textY);
180 }
181 else {
182 paintDisabledText(label, g, clippedText, textX, textY);
183 }
184 }
185 }
186 }
187
188 private String layout(JLabel label, FontMetrics fm,
189 int width, int height) {
190 Insets insets = label.getInsets(null);
191 String text = label.getText();
192 Icon icon = (label.isEnabled()) ? label.getIcon() :
193 label.getDisabledIcon();
194 Rectangle paintViewR = new Rectangle();
195 paintViewR.x = insets.left;
196 paintViewR.y = insets.top;
197 paintViewR.width = width - (insets.left + insets.right);
198 paintViewR.height = height - (insets.top + insets.bottom);
199 paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
200 paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
201 return layoutCL(label, fm, text, icon, paintViewR, paintIconR,
202 paintTextR);
203 }
204
205 public Dimension getPreferredSize(JComponent c)
206 {
207 JLabel label = (JLabel)c;
208 String text = label.getText();
209 Icon icon = (label.isEnabled()) ? label.getIcon() :
210 label.getDisabledIcon();
211 Insets insets = label.getInsets(null);
212 Font font = label.getFont();
213
214 int dx = insets.left + insets.right;
215 int dy = insets.top + insets.bottom;
216
217 if ((icon == null) &&
218 ((text == null) ||
219 ((text != null) && (font == null)))) {
220 return new Dimension(dx, dy);
221 }
222 else if ((text == null) || ((icon != null) && (font == null))) {
223 return new Dimension(icon.getIconWidth() + dx,
224 icon.getIconHeight() + dy);
225 }
226 else {
227 FontMetrics fm = label.getFontMetrics(font);
228 Rectangle iconR = new Rectangle();
229 Rectangle textR = new Rectangle();
230 Rectangle viewR = new Rectangle();
231
232 iconR.x = iconR.y = iconR.width = iconR.height = 0;
233 textR.x = textR.y = textR.width = textR.height = 0;
234 viewR.x = dx;
235 viewR.y = dy;
236 viewR.width = viewR.height = Short.MAX_VALUE;
237
238 layoutCL(label, fm, text, icon, viewR, iconR, textR);
239 int x1 = Math.min(iconR.x, textR.x);
240 int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
241 int y1 = Math.min(iconR.y, textR.y);
242 int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
243 Dimension rv = new Dimension(x2 - x1, y2 - y1);
244
245 rv.width += dx;
246 rv.height += dy;
247 return rv;
248 }
249 }
250
251
252 /**
253 * @return getPreferredSize(c)
254 */
255 public Dimension getMinimumSize(JComponent c) {
256 Dimension d = getPreferredSize(c);
257 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
258 if (v != null) {
259 d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
260 }
261 return d;
262 }
263
264 /**
265 * @return getPreferredSize(c)
266 */
267 public Dimension getMaximumSize(JComponent c) {
268 Dimension d = getPreferredSize(c);
269 View v = (View) c.getClientProperty(BasicHTML.propertyKey);
270 if (v != null) {
271 d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
272 }
273 return d;
274 }
275
276 /**
277 * Returns the baseline.
278 *
279 * @throws NullPointerException {@inheritDoc}
280 * @throws IllegalArgumentException {@inheritDoc}
281 * @see javax.swing.JComponent#getBaseline(int, int)
282 * @since 1.6
283 */
284 public int getBaseline(JComponent c, int width, int height) {
285 super.getBaseline(c, width, height);
286 JLabel label = (JLabel)c;
287 String text = label.getText();
288 if (text == null || "".equals(text) || label.getFont() == null) {
289 return -1;
290 }
291 FontMetrics fm = label.getFontMetrics(label.getFont());
292 layout(label, fm, width, height);
293 return BasicHTML.getBaseline(label, paintTextR.y, fm.getAscent(),
294 paintTextR.width, paintTextR.height);
295 }
296
297 /**
298 * Returns an enum indicating how the baseline of the component
299 * changes as the size changes.
300 *
301 * @throws NullPointerException {@inheritDoc}
302 * @see javax.swing.JComponent#getBaseline(int, int)
303 * @since 1.6
304 */
305 public Component.BaselineResizeBehavior getBaselineResizeBehavior(
306 JComponent c) {
307 super.getBaselineResizeBehavior(c);
308 if (c.getClientProperty(BasicHTML.propertyKey) != null) {
309 return Component.BaselineResizeBehavior.OTHER;
310 }
311 switch(((JLabel)c).getVerticalAlignment()) {
312 case JLabel.TOP:
313 return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
314 case JLabel.BOTTOM:
315 return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
316 case JLabel.CENTER:
317 return Component.BaselineResizeBehavior.CENTER_OFFSET;
318 }
319 return Component.BaselineResizeBehavior.OTHER;
320 }
321
322
323 public void installUI(JComponent c) {
324 installDefaults((JLabel)c);
325 installComponents((JLabel)c);
326 installListeners((JLabel)c);
327 installKeyboardActions((JLabel)c);
328 }
329
330
331 public void uninstallUI(JComponent c) {
332 uninstallDefaults((JLabel)c);
333 uninstallComponents((JLabel)c);
334 uninstallListeners((JLabel)c);
335 uninstallKeyboardActions((JLabel)c);
336 }
337
338 protected void installDefaults(JLabel c){
339 LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground", "Label.font");
340 LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
341 }
342
343 protected void installListeners(JLabel c){
344 c.addPropertyChangeListener(this);
345 }
346
347 protected void installComponents(JLabel c){
348 BasicHTML.updateRenderer(c, c.getText());
349 c.setInheritsPopupMenu(true);
350 }
351
352 protected void installKeyboardActions(JLabel l) {
353 int dka = l.getDisplayedMnemonic();
354 Component lf = l.getLabelFor();
355 if ((dka != 0) && (lf != null)) {
356 LazyActionMap.installLazyActionMap(l, BasicLabelUI.class,
357 "Label.actionMap");
358 InputMap inputMap = SwingUtilities.getUIInputMap
359 (l, JComponent.WHEN_IN_FOCUSED_WINDOW);
360 if (inputMap == null) {
361 inputMap = new ComponentInputMapUIResource(l);
362 SwingUtilities.replaceUIInputMap(l,
363 JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
364 }
365 inputMap.clear();
366 inputMap.put(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK,
367 false), "press");
368 }
369 else {
370 InputMap inputMap = SwingUtilities.getUIInputMap
371 (l, JComponent.WHEN_IN_FOCUSED_WINDOW);
372 if (inputMap != null) {
373 inputMap.clear();
374 }
375 }
376 }
377
378 protected void uninstallDefaults(JLabel c){
379 }
380
381 protected void uninstallListeners(JLabel c){
382 c.removePropertyChangeListener(this);
383 }
384
385 protected void uninstallComponents(JLabel c){
386 BasicHTML.updateRenderer(c, "");
387 }
388
389 protected void uninstallKeyboardActions(JLabel c) {
390 SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_FOCUSED, null);
391 SwingUtilities.replaceUIInputMap(c, JComponent.WHEN_IN_FOCUSED_WINDOW,
392 null);
393 SwingUtilities.replaceUIActionMap(c, null);
394 }
395
396 public static ComponentUI createUI(JComponent c) {
397 if (System.getSecurityManager() != null) {
398 AppContext appContext = AppContext.getAppContext();
399 BasicLabelUI safeBasicLabelUI =
400 (BasicLabelUI) appContext.get(BASIC_LABEL_UI_KEY);
401 if (safeBasicLabelUI == null) {
402 safeBasicLabelUI = new BasicLabelUI();
403 appContext.put(BASIC_LABEL_UI_KEY, safeBasicLabelUI);
404 }
405 return safeBasicLabelUI;
406 }
407 return labelUI;
408 }
409
410 public void propertyChange(PropertyChangeEvent e) {
411 String name = e.getPropertyName();
412 if (name == "text" || "font" == name || "foreground" == name) {
413 // remove the old html view client property if one
414 // existed, and install a new one if the text installed
415 // into the JLabel is html source.
416 JLabel lbl = ((JLabel) e.getSource());
417 String text = lbl.getText();
418 BasicHTML.updateRenderer(lbl, text);
419 }
420 else if (name == "labelFor" || name == "displayedMnemonic") {
421 installKeyboardActions((JLabel) e.getSource());
422 }
423 }
424
425 // When the accelerator is pressed, temporarily make the JLabel
426 // focusTraversable by registering a WHEN_FOCUSED action for the
427 // release of the accelerator. Then give it focus so it can
428 // prevent unwanted keyTyped events from getting to other components.
429 private static class Actions extends UIAction {
430 private static final String PRESS = "press";
431 private static final String RELEASE = "release";
432
433 Actions(String key) {
434 super(key);
435 }
436
437 public void actionPerformed(ActionEvent e) {
438 JLabel label = (JLabel)e.getSource();
439 String key = getName();
440 if (key == PRESS) {
441 doPress(label);
442 }
443 else if (key == RELEASE) {
444 doRelease(label);
445 }
446 }
447
448 private void doPress(JLabel label) {
449 Component labelFor = label.getLabelFor();
450 if (labelFor != null && labelFor.isEnabled()) {
451 InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED);
452 if (inputMap == null) {
453 inputMap = new InputMapUIResource();
454 SwingUtilities.replaceUIInputMap(label, JComponent.WHEN_FOCUSED, inputMap);
455 }
456 int dka = label.getDisplayedMnemonic();
457 inputMap.put(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK, true), RELEASE);
458 // Need this when the sticky keys are enabled
459 inputMap.put(KeyStroke.getKeyStroke(dka, 0, true), RELEASE);
460 // Need this if ALT is released before the accelerator
461 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true), RELEASE);
462 label.requestFocus();
463 }
464 }
465
466 private void doRelease(JLabel label) {
467 Component labelFor = label.getLabelFor();
468 if (labelFor != null && labelFor.isEnabled()) {
469 InputMap inputMap = SwingUtilities.getUIInputMap(label, JComponent.WHEN_FOCUSED);
470 if (inputMap != null) {
471 // inputMap should never be null.
472 int dka = label.getDisplayedMnemonic();
473 inputMap.remove(KeyStroke.getKeyStroke(dka, ActionEvent.ALT_MASK, true));
474 inputMap.remove(KeyStroke.getKeyStroke(dka, 0, true));
475 inputMap.remove(KeyStroke.getKeyStroke(KeyEvent.VK_ALT, 0, true));
476 }
477 if (labelFor instanceof Container &&
478 ((Container) labelFor).isFocusCycleRoot()) {
479 labelFor.requestFocus();
480 } else {
481 SwingUtilities2.compositeRequestFocus(labelFor);
482 }
483 }
484 }
485 }
486}