1. /*
  2. * @(#)JLabel.java 1.113 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.Component;
  9. import java.awt.Font;
  10. import java.awt.Image;
  11. import java.awt.*;
  12. import java.text.*;
  13. import java.awt.geom.*;
  14. import java.io.ObjectOutputStream;
  15. import java.io.ObjectInputStream;
  16. import java.io.IOException;
  17. import javax.swing.plaf.LabelUI;
  18. import javax.accessibility.*;
  19. import javax.swing.text.*;
  20. import javax.swing.text.html.*;
  21. import javax.swing.plaf.basic.*;
  22. import java.util.*;
  23. /**
  24. * A display area for a short text string or an image,
  25. * or both.
  26. * A label does not react to input events.
  27. * As a result, it cannot get the keyboard focus.
  28. * A label can, however, display a keyboard alternative
  29. * as a convenience for a nearby component
  30. * that has a keyboard alternative but can't display it.
  31. * <p>
  32. * A <code>JLabel</code> object can display
  33. * either text, an image, or both.
  34. * You can specify where in the label's display area
  35. * the label's contents are aligned
  36. * by setting the vertical and horizontal alignment.
  37. * By default, labels are vertically centered
  38. * in their display area.
  39. * Text-only labels are leading edge aligned, by default;
  40. * image-only labels are horizontally centered, by default.
  41. * <p>
  42. * You can also specify the position of the text
  43. * relative to the image.
  44. * By default, text is on the trailing edge of the image,
  45. * with the text and image vertically aligned.
  46. * <p>
  47. * A label's leading and trailing edge are determined from the value of its
  48. * {@link java.awt.ComponentOrientation} property. At present, the default
  49. * ComponentOrientation setting maps the leading edge to left and the trailing
  50. * edge to right.
  51. *
  52. * <p>
  53. * Finally, you can use the <code>setIconTextGap</code> method
  54. * to specify how many pixels
  55. * should appear between the text and the image.
  56. * The default is 4 pixels.
  57. * <p>
  58. * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/label.html">How to Use Labels</a>
  59. * in <em>The Java Tutorial</em>
  60. * for further documentation.
  61. * <p>
  62. * <strong>Warning:</strong>
  63. * Serialized objects of this class will not be compatible with
  64. * future Swing releases. The current serialization support is
  65. * appropriate for short term storage or RMI between applications running
  66. * the same version of Swing. As of 1.4, support for long term storage
  67. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  68. * has been added to the <code>java.beans</code> package.
  69. * Please see {@link java.beans.XMLEncoder}.
  70. *
  71. * @beaninfo
  72. * attribute: isContainer false
  73. * description: A component that displays a short string and an icon.
  74. *
  75. * @version 1.113 01/23/03
  76. * @author Hans Muller
  77. */
  78. public class JLabel extends JComponent implements SwingConstants, Accessible
  79. {
  80. /**
  81. * @see #getUIClassID
  82. * @see #readObject
  83. */
  84. private static final String uiClassID = "LabelUI";
  85. private int mnemonic = '\0';
  86. private int mnemonicIndex = -1;
  87. private String text = ""; // "" rather than null, for BeanBox
  88. private Icon defaultIcon = null;
  89. private Icon disabledIcon = null;
  90. private boolean disabledIconSet = false;
  91. private int verticalAlignment = CENTER;
  92. private int horizontalAlignment = LEADING;
  93. private int verticalTextPosition = CENTER;
  94. private int horizontalTextPosition = TRAILING;
  95. private int iconTextGap = 4;
  96. protected Component labelFor = null;
  97. private AccessibleIcon accessibleIcon = null;
  98. /**
  99. * Client property key used to determine what label is labeling the
  100. * component. This is generally not used by labels, but is instead
  101. * used by components such as text areas that are being labeled by
  102. * labels. When the labelFor property of a label is set, it will
  103. * automatically set the LABELED_BY_PROPERTY of the component being
  104. * labelled.
  105. *
  106. * @see #setLabelFor
  107. */
  108. static final String LABELED_BY_PROPERTY = "labeledBy";
  109. /**
  110. * Creates a <code>JLabel</code> instance with the specified
  111. * text, image, and horizontal alignment.
  112. * The label is centered vertically in its display area.
  113. * The text is on the trailing edge of the image.
  114. *
  115. * @param text The text to be displayed by the label.
  116. * @param icon The image to be displayed by the label.
  117. * @param horizontalAlignment One of the following constants
  118. * defined in <code>SwingConstants</code>:
  119. * <code>LEFT</code>,
  120. * <code>CENTER</code>,
  121. * <code>RIGHT</code>,
  122. * <code>LEADING</code> or
  123. * <code>TRAILING</code>.
  124. */
  125. public JLabel(String text, Icon icon, int horizontalAlignment) {
  126. setText(text);
  127. setIcon(icon);
  128. setHorizontalAlignment(horizontalAlignment);
  129. updateUI();
  130. setAlignmentX(LEFT_ALIGNMENT);
  131. }
  132. /**
  133. * Creates a <code>JLabel</code> instance with the specified
  134. * text and horizontal alignment.
  135. * The label is centered vertically in its display area.
  136. *
  137. * @param text The text to be displayed by the label.
  138. * @param horizontalAlignment One of the following constants
  139. * defined in <code>SwingConstants</code>:
  140. * <code>LEFT</code>,
  141. * <code>CENTER</code>,
  142. * <code>RIGHT</code>,
  143. * <code>LEADING</code> or
  144. * <code>TRAILING</code>.
  145. */
  146. public JLabel(String text, int horizontalAlignment) {
  147. this(text, null, horizontalAlignment);
  148. }
  149. /**
  150. * Creates a <code>JLabel</code> instance with the specified text.
  151. * The label is aligned against the leading edge of its display area,
  152. * and centered vertically.
  153. *
  154. * @param text The text to be displayed by the label.
  155. */
  156. public JLabel(String text) {
  157. this(text, null, LEADING);
  158. }
  159. /**
  160. * Creates a <code>JLabel</code> instance with the specified
  161. * image and horizontal alignment.
  162. * The label is centered vertically in its display area.
  163. *
  164. * @param image The image to be displayed by the label.
  165. * @param horizontalAlignment One of the following constants
  166. * defined in <code>SwingConstants</code>:
  167. * <code>LEFT</code>,
  168. * <code>CENTER</code>,
  169. * <code>RIGHT</code>,
  170. * <code>LEADING</code> or
  171. * <code>TRAILING</code>.
  172. */
  173. public JLabel(Icon image, int horizontalAlignment) {
  174. this(null, image, horizontalAlignment);
  175. }
  176. /**
  177. * Creates a <code>JLabel</code> instance with the specified image.
  178. * The label is centered vertically and horizontally
  179. * in its display area.
  180. *
  181. * @param image The image to be displayed by the label.
  182. */
  183. public JLabel(Icon image) {
  184. this(null, image, CENTER);
  185. }
  186. /**
  187. * Creates a <code>JLabel</code> instance with
  188. * no image and with an empty string for the title.
  189. * The label is centered vertically
  190. * in its display area.
  191. * The label's contents, once set, will be displayed on the leading edge
  192. * of the label's display area.
  193. */
  194. public JLabel() {
  195. this("", null, LEADING);
  196. }
  197. /**
  198. * Returns the L&F object that renders this component.
  199. *
  200. * @return LabelUI object
  201. */
  202. public LabelUI getUI() {
  203. return (LabelUI)ui;
  204. }
  205. /**
  206. * Sets the L&F object that renders this component.
  207. *
  208. * @param ui the LabelUI L&F object
  209. * @see UIDefaults#getUI
  210. * @beaninfo
  211. * bound: true
  212. * hidden: true
  213. * attribute: visualUpdate true
  214. * description: The UI object that implements the Component's LookAndFeel.
  215. */
  216. public void setUI(LabelUI ui) {
  217. super.setUI(ui);
  218. }
  219. /**
  220. * Resets the UI property to a value from the current look and feel.
  221. *
  222. * @see JComponent#updateUI
  223. */
  224. public void updateUI() {
  225. setUI((LabelUI)UIManager.getUI(this));
  226. }
  227. /**
  228. * Returns a string that specifies the name of the l&f class
  229. * that renders this component.
  230. *
  231. * @return String "LabelUI"
  232. *
  233. * @see JComponent#getUIClassID
  234. * @see UIDefaults#getUI
  235. */
  236. public String getUIClassID() {
  237. return uiClassID;
  238. }
  239. /**
  240. * Returns the text string that the label displays.
  241. *
  242. * @return a String
  243. * @see #setText
  244. */
  245. public String getText() {
  246. return text;
  247. }
  248. /**
  249. * Defines the single line of text this component will display. If
  250. * the value of text is null or empty string, nothing is displayed.
  251. * <p>
  252. * The default value of this property is null.
  253. * <p>
  254. * This is a JavaBeans bound property.
  255. *
  256. * @see #setVerticalTextPosition
  257. * @see #setHorizontalTextPosition
  258. * @see #setIcon
  259. * @beaninfo
  260. * preferred: true
  261. * bound: true
  262. * attribute: visualUpdate true
  263. * description: Defines the single line of text this component will display.
  264. */
  265. public void setText(String text) {
  266. String oldAccessibleName = null;
  267. if (accessibleContext != null) {
  268. oldAccessibleName = accessibleContext.getAccessibleName();
  269. }
  270. String oldValue = this.text;
  271. this.text = text;
  272. firePropertyChange("text", oldValue, text);
  273. setDisplayedMnemonicIndex(
  274. SwingUtilities.findDisplayedMnemonicIndex(
  275. text, getDisplayedMnemonic()));
  276. if ((accessibleContext != null)
  277. && (accessibleContext.getAccessibleName() != oldAccessibleName)) {
  278. accessibleContext.firePropertyChange(
  279. AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
  280. oldAccessibleName,
  281. accessibleContext.getAccessibleName());
  282. }
  283. if (text == null || oldValue == null || !text.equals(oldValue)) {
  284. revalidate();
  285. repaint();
  286. }
  287. }
  288. /**
  289. * Returns the graphic image (glyph, icon) that the label displays.
  290. *
  291. * @return an Icon
  292. * @see #setIcon
  293. */
  294. public Icon getIcon() {
  295. return defaultIcon;
  296. }
  297. /**
  298. * Defines the icon this component will display. If
  299. * the value of icon is null, nothing is displayed.
  300. * <p>
  301. * The default value of this property is null.
  302. * <p>
  303. * This is a JavaBeans bound property.
  304. *
  305. * @see #setVerticalTextPosition
  306. * @see #setHorizontalTextPosition
  307. * @see #getIcon
  308. * @beaninfo
  309. * preferred: true
  310. * bound: true
  311. * attribute: visualUpdate true
  312. * description: The icon this component will display.
  313. */
  314. public void setIcon(Icon icon) {
  315. Icon oldValue = defaultIcon;
  316. defaultIcon = icon;
  317. /* If the default icon has really changed and we had
  318. * generated the disabled icon for this component
  319. * (in other words, setDisabledIcon() was never called), then
  320. * clear the disabledIcon field.
  321. */
  322. if ((defaultIcon != oldValue) && !disabledIconSet) {
  323. disabledIcon = null;
  324. }
  325. firePropertyChange("icon", oldValue, defaultIcon);
  326. if ((accessibleContext != null) && (oldValue != defaultIcon)) {
  327. accessibleContext.firePropertyChange(
  328. AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
  329. oldValue, defaultIcon);
  330. }
  331. /* If the default icon has changed and the new one is
  332. * a different size, then revalidate. Repaint if the
  333. * default icon has changed.
  334. */
  335. if (defaultIcon != oldValue) {
  336. if ((defaultIcon == null) ||
  337. (oldValue == null) ||
  338. (defaultIcon.getIconWidth() != oldValue.getIconWidth()) ||
  339. (defaultIcon.getIconHeight() != oldValue.getIconHeight())) {
  340. revalidate();
  341. }
  342. repaint();
  343. }
  344. // set the accessible icon
  345. accessibleIcon = null;
  346. if (defaultIcon instanceof Accessible) {
  347. AccessibleContext ac =
  348. ((Accessible)defaultIcon).getAccessibleContext();
  349. if (ac != null && ac instanceof AccessibleIcon) {
  350. accessibleIcon = (AccessibleIcon)ac;
  351. }
  352. }
  353. }
  354. /**
  355. * Returns the value of the disabledIcon property if it's been set,
  356. * If it hasn't been set and the value of the icon property is
  357. * an ImageIcon, we compute a "grayed out" version of the icon and
  358. * update the disabledIcon property with that.
  359. *
  360. * @return The value of the disabledIcon property.
  361. * @see #setDisabledIcon
  362. * @see ImageIcon
  363. */
  364. public Icon getDisabledIcon()
  365. {
  366. if(!disabledIconSet &&
  367. (disabledIcon == null) &&
  368. (defaultIcon != null) &&
  369. (defaultIcon instanceof ImageIcon)) {
  370. Image grayImage = GrayFilter.createDisabledImage(((ImageIcon)defaultIcon).getImage());
  371. disabledIcon = new ImageIcon(grayImage);
  372. firePropertyChange("disabledIcon", null, disabledIcon);
  373. }
  374. return disabledIcon;
  375. }
  376. /**
  377. * Set the icon to be displayed if this JLabel is "disabled"
  378. * (JLabel.setEnabled(false)).
  379. * <p>
  380. * The default value of this property is null.
  381. *
  382. * @param disabledIcon the Icon to display when the component is disabled
  383. * @see #getDisabledIcon
  384. * @see #setEnabled
  385. * @beaninfo
  386. * bound: true
  387. * attribute: visualUpdate true
  388. * description: The icon to display if the label is disabled.
  389. */
  390. public void setDisabledIcon(Icon disabledIcon) {
  391. Icon oldValue = this.disabledIcon;
  392. this.disabledIcon = disabledIcon;
  393. disabledIconSet = (disabledIcon != null);
  394. firePropertyChange("disabledIcon", oldValue, disabledIcon);
  395. if (disabledIcon != oldValue) {
  396. if (disabledIcon == null || oldValue == null ||
  397. disabledIcon.getIconWidth() != oldValue.getIconWidth() ||
  398. disabledIcon.getIconHeight() != oldValue.getIconHeight()) {
  399. revalidate();
  400. }
  401. if (!isEnabled()) {
  402. repaint();
  403. }
  404. }
  405. }
  406. /**
  407. * Specify a keycode that indicates a mnemonic key.
  408. * This property is used when the label is part of a larger component.
  409. * If the labelFor property of the label is not null, the label will
  410. * call the requestFocus method of the component specified by the
  411. * labelFor property when the mnemonic is activated.
  412. *
  413. * @see #getLabelFor
  414. * @see #setLabelFor
  415. * @beaninfo
  416. * bound: true
  417. * attribute: visualUpdate true
  418. * description: The mnemonic keycode.
  419. */
  420. public void setDisplayedMnemonic(int key) {
  421. int oldKey = mnemonic;
  422. mnemonic = key;
  423. firePropertyChange("displayedMnemonic", oldKey, mnemonic);
  424. setDisplayedMnemonicIndex(
  425. SwingUtilities.findDisplayedMnemonicIndex(getText(), mnemonic));
  426. if (key != oldKey) {
  427. revalidate();
  428. repaint();
  429. }
  430. }
  431. /**
  432. * Specifies the displayedMnemonic as a char value.
  433. *
  434. * @param aChar a char specifying the mnemonic to display
  435. * @see #setDisplayedMnemonic(int)
  436. */
  437. public void setDisplayedMnemonic(char aChar) {
  438. int vk = (int) aChar;
  439. if(vk >= 'a' && vk <='z')
  440. vk -= ('a' - 'A');
  441. setDisplayedMnemonic(vk);
  442. }
  443. /**
  444. * Return the keycode that indicates a mnemonic key.
  445. * This property is used when the label is part of a larger component.
  446. * If the labelFor property of the label is not null, the label will
  447. * call the requestFocus method of the component specified by the
  448. * labelFor property when the mnemonic is activated.
  449. *
  450. * @return int value for the mnemonic key
  451. *
  452. * @see #getLabelFor
  453. * @see #setLabelFor
  454. */
  455. public int getDisplayedMnemonic() {
  456. return mnemonic;
  457. }
  458. /**
  459. * Provides a hint to the look and feel as to which character in the
  460. * text should be decorated to represent the mnemonic. Not all look and
  461. * feels may support this. A value of -1 indicates either there is no
  462. * mnemonic, the mnemonic character is not contained in the string, or
  463. * the developer does not wish the mnemonic to be displayed.
  464. * <p>
  465. * The value of this is updated as the properties relating to the
  466. * mnemonic change (such as the mnemonic itself, the text...).
  467. * You should only ever have to call this if
  468. * you do not wish the default character to be underlined. For example, if
  469. * the text was 'Save As', with a mnemonic of 'a', and you wanted the 'A'
  470. * to be decorated, as 'Save <u>A</u>s', you would have to invoke
  471. * <code>setDisplayedMnemonicIndex(5)</code> after invoking
  472. * <code>setMnemonic(KeyEvent.VK_A)</code>.
  473. *
  474. * @since 1.4
  475. * @param index Index into the String to underline
  476. * @exception IllegalArgumentException will be thrown if <code>index</code
  477. * is >= length of the text, or < -1
  478. *
  479. * @beaninfo
  480. * bound: true
  481. * attribute: visualUpdate true
  482. * description: the index into the String to draw the keyboard character
  483. * mnemonic at
  484. */
  485. public void setDisplayedMnemonicIndex(int index)
  486. throws IllegalArgumentException {
  487. int oldValue = mnemonicIndex;
  488. if (index == -1) {
  489. mnemonicIndex = -1;
  490. } else {
  491. String text = getText();
  492. int textLength = (text == null) ? 0 : text.length();
  493. if (index < -1 || index >= textLength) { // index out of range
  494. throw new IllegalArgumentException("index == " + index);
  495. }
  496. }
  497. mnemonicIndex = index;
  498. firePropertyChange("displayedMnemonicIndex", oldValue, index);
  499. if (index != oldValue) {
  500. revalidate();
  501. repaint();
  502. }
  503. }
  504. /**
  505. * Returns the character, as an index, that the look and feel should
  506. * provide decoration for as representing the mnemonic character.
  507. *
  508. * @since 1.4
  509. * @return index representing mnemonic character
  510. * @see #setDisplayedMnemonicIndex
  511. */
  512. public int getDisplayedMnemonicIndex() {
  513. return mnemonicIndex;
  514. }
  515. /**
  516. * Verify that key is a legal value for the horizontalAlignment properties.
  517. *
  518. * @param key the property value to check
  519. * @param message the IllegalArgumentException detail message
  520. * @exception IllegalArgumentException if key isn't LEFT, CENTER, RIGHT,
  521. * LEADING or TRAILING.
  522. * @see #setHorizontalTextPosition
  523. * @see #setHorizontalAlignment
  524. */
  525. protected int checkHorizontalKey(int key, String message) {
  526. if ((key == LEFT) ||
  527. (key == CENTER) ||
  528. (key == RIGHT) ||
  529. (key == LEADING) ||
  530. (key == TRAILING)) {
  531. return key;
  532. }
  533. else {
  534. throw new IllegalArgumentException(message);
  535. }
  536. }
  537. /**
  538. * Verify that key is a legal value for the
  539. * verticalAlignment or verticalTextPosition properties.
  540. *
  541. * @param key the property value to check
  542. * @param message the IllegalArgumentException detail message
  543. * @exception IllegalArgumentException if key isn't TOP, CENTER, or BOTTOM.
  544. * @see #setVerticalAlignment
  545. * @see #setVerticalTextPosition
  546. */
  547. protected int checkVerticalKey(int key, String message) {
  548. if ((key == TOP) || (key == CENTER) || (key == BOTTOM)) {
  549. return key;
  550. }
  551. else {
  552. throw new IllegalArgumentException(message);
  553. }
  554. }
  555. /**
  556. * Returns the amount of space between the text and the icon
  557. * displayed in this label.
  558. *
  559. * @return an int equal to the number of pixels between the text
  560. * and the icon.
  561. * @see #setIconTextGap
  562. */
  563. public int getIconTextGap() {
  564. return iconTextGap;
  565. }
  566. /**
  567. * If both the icon and text properties are set, this property
  568. * defines the space between them.
  569. * <p>
  570. * The default value of this property is 4 pixels.
  571. * <p>
  572. * This is a JavaBeans bound property.
  573. *
  574. * @see #getIconTextGap
  575. * @beaninfo
  576. * bound: true
  577. * attribute: visualUpdate true
  578. * description: If both the icon and text properties are set, this
  579. * property defines the space between them.
  580. */
  581. public void setIconTextGap(int iconTextGap) {
  582. int oldValue = this.iconTextGap;
  583. this.iconTextGap = iconTextGap;
  584. firePropertyChange("iconTextGap", oldValue, iconTextGap);
  585. if (iconTextGap != oldValue) {
  586. revalidate();
  587. repaint();
  588. }
  589. }
  590. /**
  591. * Returns the alignment of the label's contents along the Y axis.
  592. *
  593. * @return The value of the verticalAlignment property, one of the
  594. * following constants defined in <code>SwingConstants</code>:
  595. * <code>TOP</code>,
  596. * <code>CENTER</code>, or
  597. * <code>BOTTOM</code>.
  598. *
  599. * @see SwingConstants
  600. * @see #setVerticalAlignment
  601. */
  602. public int getVerticalAlignment() {
  603. return verticalAlignment;
  604. }
  605. /**
  606. * Sets the alignment of the label's contents along the Y axis.
  607. * <p>
  608. * The default value of this property is CENTER.
  609. *
  610. * @param alignment One of the following constants
  611. * defined in <code>SwingConstants</code>:
  612. * <code>TOP</code>,
  613. * <code>CENTER</code> (the default), or
  614. * <code>BOTTOM</code>.
  615. *
  616. * @see SwingConstants
  617. * @see #getVerticalAlignment
  618. * @beaninfo
  619. * bound: true
  620. * enum: TOP SwingConstants.TOP
  621. * CENTER SwingConstants.CENTER
  622. * BOTTOM SwingConstants.BOTTOM
  623. * attribute: visualUpdate true
  624. * description: The alignment of the label's contents along the Y axis.
  625. */
  626. public void setVerticalAlignment(int alignment) {
  627. if (alignment == verticalAlignment) return;
  628. int oldValue = verticalAlignment;
  629. verticalAlignment = checkVerticalKey(alignment, "verticalAlignment");
  630. firePropertyChange("verticalAlignment", oldValue, verticalAlignment);
  631. repaint();
  632. }
  633. /**
  634. * Returns the alignment of the label's contents along the X axis.
  635. *
  636. * @return The value of the horizontalAlignment property, one of the
  637. * following constants defined in <code>SwingConstants</code>:
  638. * <code>LEFT</code>,
  639. * <code>CENTER</code>,
  640. * <code>RIGHT</code>,
  641. * <code>LEADING</code> or
  642. * <code>TRAILING</code>.
  643. *
  644. * @see #setHorizontalAlignment
  645. * @see SwingConstants
  646. */
  647. public int getHorizontalAlignment() {
  648. return horizontalAlignment;
  649. }
  650. /**
  651. * Sets the alignment of the label's contents along the X axis.
  652. * <p>
  653. * This is a JavaBeans bound property.
  654. *
  655. * @param alignment One of the following constants
  656. * defined in <code>SwingConstants</code>:
  657. * <code>LEFT</code>,
  658. * <code>CENTER</code> (the default for image-only labels),
  659. * <code>RIGHT</code>,
  660. * <code>LEADING</code> (the default for text-only labels) or
  661. * <code>TRAILING</code>.
  662. *
  663. * @see SwingConstants
  664. * @see #getHorizontalAlignment
  665. * @beaninfo
  666. * bound: true
  667. * enum: LEFT SwingConstants.LEFT
  668. * CENTER SwingConstants.CENTER
  669. * RIGHT SwingConstants.RIGHT
  670. * LEADING SwingConstants.LEADING
  671. * TRAILING SwingConstants.TRAILING
  672. * attribute: visualUpdate true
  673. * description: The alignment of the label's content along the X axis.
  674. */
  675. public void setHorizontalAlignment(int alignment) {
  676. if (alignment == horizontalAlignment) return;
  677. int oldValue = horizontalAlignment;
  678. horizontalAlignment = checkHorizontalKey(alignment,
  679. "horizontalAlignment");
  680. firePropertyChange("horizontalAlignment",
  681. oldValue, horizontalAlignment);
  682. repaint();
  683. }
  684. /**
  685. * Returns the vertical position of the label's text,
  686. * relative to its image.
  687. *
  688. * @return One of the following constants
  689. * defined in <code>SwingConstants</code>:
  690. * <code>TOP</code>,
  691. * <code>CENTER</code>, or
  692. * <code>BOTTOM</code>.
  693. *
  694. * @see #setVerticalTextPosition
  695. * @see SwingConstants
  696. */
  697. public int getVerticalTextPosition() {
  698. return verticalTextPosition;
  699. }
  700. /**
  701. * Sets the vertical position of the label's text,
  702. * relative to its image.
  703. * <p>
  704. * The default value of this property is CENTER.
  705. * <p>
  706. * This is a JavaBeans bound property.
  707. *
  708. * @param textPosition One of the following constants
  709. * defined in <code>SwingConstants</code>:
  710. * <code>TOP</code>,
  711. * <code>CENTER</code> (the default), or
  712. * <code>BOTTOM</code>.
  713. *
  714. * @see SwingConstants
  715. * @see #getVerticalTextPosition
  716. * @beaninfo
  717. * bound: true
  718. * enum: TOP SwingConstants.TOP
  719. * CENTER SwingConstants.CENTER
  720. * BOTTOM SwingConstants.BOTTOM
  721. * expert: true
  722. * attribute: visualUpdate true
  723. * description: The vertical position of the text relative to it's image.
  724. */
  725. public void setVerticalTextPosition(int textPosition) {
  726. if (textPosition == verticalTextPosition) return;
  727. int old = verticalTextPosition;
  728. verticalTextPosition = checkVerticalKey(textPosition,
  729. "verticalTextPosition");
  730. firePropertyChange("verticalTextPosition", old, verticalTextPosition);
  731. repaint();
  732. }
  733. /**
  734. * Returns the horizontal position of the label's text,
  735. * relative to its image.
  736. *
  737. * @return One of the following constants
  738. * defined in <code>SwingConstants</code>:
  739. * <code>LEFT</code>,
  740. * <code>CENTER</code>,
  741. * <code>RIGHT</code>,
  742. * <code>LEADING</code> or
  743. * <code>TRAILING</code>.
  744. *
  745. * @see SwingConstants
  746. */
  747. public int getHorizontalTextPosition() {
  748. return horizontalTextPosition;
  749. }
  750. /**
  751. * Sets the horizontal position of the label's text,
  752. * relative to its image.
  753. *
  754. * @param textPosition One of the following constants
  755. * defined in <code>SwingConstants</code>:
  756. * <code>LEFT</code>,
  757. * <code>CENTER</code>,
  758. * <code>RIGHT</code>,
  759. * <code>LEADING</code>, or
  760. * <code>TRAILING</code> (the default).
  761. * @exception IllegalArgumentException
  762. *
  763. * @see SwingConstants
  764. * @beaninfo
  765. * expert: true
  766. * bound: true
  767. * enum: LEFT SwingConstants.LEFT
  768. * CENTER SwingConstants.CENTER
  769. * RIGHT SwingConstants.RIGHT
  770. * LEADING SwingConstants.LEADING
  771. * TRAILING SwingConstants.TRAILING
  772. * attribute: visualUpdate true
  773. * description: The horizontal position of the label's text,
  774. * relative to its image.
  775. */
  776. public void setHorizontalTextPosition(int textPosition) {
  777. int old = horizontalTextPosition;
  778. this.horizontalTextPosition = checkHorizontalKey(textPosition,
  779. "horizontalTextPosition");
  780. firePropertyChange("horizontalTextPosition",
  781. old, horizontalTextPosition);
  782. repaint();
  783. }
  784. /**
  785. * This is overridden to return false if the current Icon's Image is
  786. * not equal to the passed in Image <code>img</code>.
  787. *
  788. * @see java.awt.image.ImageObserver
  789. * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int)
  790. */
  791. public boolean imageUpdate(Image img, int infoflags,
  792. int x, int y, int w, int h) {
  793. // Don't use getDisabledIcon, will trigger creation of icon if icon
  794. // not set.
  795. if (!isShowing() ||
  796. !SwingUtilities.doesIconReferenceImage(getIcon(), img) &&
  797. !SwingUtilities.doesIconReferenceImage(disabledIcon, img)) {
  798. return false;
  799. }
  800. return super.imageUpdate(img, infoflags, x, y, w, h);
  801. }
  802. /**
  803. * See readObject() and writeObject() in JComponent for more
  804. * information about serialization in Swing.
  805. */
  806. private void writeObject(ObjectOutputStream s) throws IOException {
  807. s.defaultWriteObject();
  808. if (getUIClassID().equals(uiClassID)) {
  809. byte count = JComponent.getWriteObjCounter(this);
  810. JComponent.setWriteObjCounter(this, --count);
  811. if (count == 0 && ui != null) {
  812. ui.installUI(this);
  813. }
  814. }
  815. }
  816. /**
  817. * Returns a string representation of this JLabel. This method
  818. * is intended to be used only for debugging purposes, and the
  819. * content and format of the returned string may vary between
  820. * implementations. The returned string may be empty but may not
  821. * be <code>null</code>.
  822. *
  823. * @return a string representation of this JLabel.
  824. */
  825. protected String paramString() {
  826. String textString = (text != null ?
  827. text : "");
  828. String defaultIconString = ((defaultIcon != null)
  829. && (defaultIcon != this) ?
  830. defaultIcon.toString() : "");
  831. String disabledIconString = ((disabledIcon != null)
  832. && (disabledIcon != this) ?
  833. disabledIcon.toString() : "");
  834. String labelForString = (labelFor != null ?
  835. labelFor.toString() : "");
  836. String verticalAlignmentString;
  837. if (verticalAlignment == TOP) {
  838. verticalAlignmentString = "TOP";
  839. } else if (verticalAlignment == CENTER) {
  840. verticalAlignmentString = "CENTER";
  841. } else if (verticalAlignment == BOTTOM) {
  842. verticalAlignmentString = "BOTTOM";
  843. } else verticalAlignmentString = "";
  844. String horizontalAlignmentString;
  845. if (horizontalAlignment == LEFT) {
  846. horizontalAlignmentString = "LEFT";
  847. } else if (horizontalAlignment == CENTER) {
  848. horizontalAlignmentString = "CENTER";
  849. } else if (horizontalAlignment == RIGHT) {
  850. horizontalAlignmentString = "RIGHT";
  851. } else if (horizontalAlignment == LEADING) {
  852. horizontalAlignmentString = "LEADING";
  853. } else if (horizontalAlignment == TRAILING) {
  854. horizontalAlignmentString = "TRAILING";
  855. } else horizontalAlignmentString = "";
  856. String verticalTextPositionString;
  857. if (verticalTextPosition == TOP) {
  858. verticalTextPositionString = "TOP";
  859. } else if (verticalTextPosition == CENTER) {
  860. verticalTextPositionString = "CENTER";
  861. } else if (verticalTextPosition == BOTTOM) {
  862. verticalTextPositionString = "BOTTOM";
  863. } else verticalTextPositionString = "";
  864. String horizontalTextPositionString;
  865. if (horizontalTextPosition == LEFT) {
  866. horizontalTextPositionString = "LEFT";
  867. } else if (horizontalTextPosition == CENTER) {
  868. horizontalTextPositionString = "CENTER";
  869. } else if (horizontalTextPosition == RIGHT) {
  870. horizontalTextPositionString = "RIGHT";
  871. } else if (horizontalTextPosition == LEADING) {
  872. horizontalTextPositionString = "LEADING";
  873. } else if (horizontalTextPosition == TRAILING) {
  874. horizontalTextPositionString = "TRAILING";
  875. } else horizontalTextPositionString = "";
  876. return super.paramString() +
  877. ",defaultIcon=" + defaultIconString +
  878. ",disabledIcon=" + disabledIconString +
  879. ",horizontalAlignment=" + horizontalAlignmentString +
  880. ",horizontalTextPosition=" + horizontalTextPositionString +
  881. ",iconTextGap=" + iconTextGap +
  882. ",labelFor=" + labelForString +
  883. ",text=" + textString +
  884. ",verticalAlignment=" + verticalAlignmentString +
  885. ",verticalTextPosition=" + verticalTextPositionString;
  886. }
  887. /**
  888. * --- Accessibility Support ---
  889. */
  890. /**
  891. * Get the component this is labelling.
  892. *
  893. * @return the Component this is labelling. Can be null if this
  894. * does not label a Component. If the displayedMnemonic
  895. * property is set and the labelFor property is also set, the label
  896. * will call the requestFocus method of the component specified by the
  897. * labelFor property when the mnemonic is activated.
  898. *
  899. * @see #getDisplayedMnemonic
  900. * @see #setDisplayedMnemonic
  901. */
  902. public Component getLabelFor() {
  903. return labelFor;
  904. }
  905. /**
  906. * Set the component this is labelling. Can be null if this does not
  907. * label a Component. If the displayedMnemonic property is set
  908. * and the labelFor property is also set, the label will
  909. * call the requestFocus method of the component specified by the
  910. * labelFor property when the mnemonic is activated.
  911. *
  912. * @param c the Component this label is for, or null if the label is
  913. * not the label for a component
  914. *
  915. * @see #getDisplayedMnemonic
  916. * @see #setDisplayedMnemonic
  917. *
  918. * @beaninfo
  919. * bound: true
  920. * description: The component this is labelling.
  921. */
  922. public void setLabelFor(Component c) {
  923. Component oldC = labelFor;
  924. labelFor = c;
  925. firePropertyChange("labelFor", oldC, c);
  926. if (oldC instanceof JComponent) {
  927. ((JComponent)oldC).putClientProperty(LABELED_BY_PROPERTY, null);
  928. }
  929. if (c instanceof JComponent) {
  930. ((JComponent)c).putClientProperty(LABELED_BY_PROPERTY, this);
  931. }
  932. }
  933. /**
  934. * Get the AccessibleContext of this object
  935. *
  936. * @return the AccessibleContext of this object
  937. * @beaninfo
  938. * expert: true
  939. * description: The AccessibleContext associated with this Label.
  940. */
  941. public AccessibleContext getAccessibleContext() {
  942. if (accessibleContext == null) {
  943. accessibleContext = new AccessibleJLabel();
  944. }
  945. return accessibleContext;
  946. }
  947. /**
  948. * The class used to obtain the accessible role for this object.
  949. * <p>
  950. * <strong>Warning:</strong>
  951. * Serialized objects of this class will not be compatible with
  952. * future Swing releases. The current serialization support is
  953. * appropriate for short term storage or RMI between applications running
  954. * the same version of Swing. As of 1.4, support for long term storage
  955. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  956. * has been added to the <code>java.beans</code> package.
  957. * Please see {@link java.beans.XMLEncoder}.
  958. */
  959. protected class AccessibleJLabel extends AccessibleJComponent
  960. implements AccessibleText, AccessibleExtendedComponent {
  961. /**
  962. * Get the accessible name of this object.
  963. *
  964. * @return the localized name of the object -- can be null if this
  965. * object does not have a name
  966. * @see AccessibleContext#setAccessibleName
  967. */
  968. public String getAccessibleName() {
  969. if (accessibleName != null) {
  970. return accessibleName;
  971. } else {
  972. if (JLabel.this.getText() == null) {
  973. return super.getAccessibleName();
  974. } else {
  975. return JLabel.this.getText();
  976. }
  977. }
  978. }
  979. /**
  980. * Get the role of this object.
  981. *
  982. * @return an instance of AccessibleRole describing the role of the
  983. * object
  984. * @see AccessibleRole
  985. */
  986. public AccessibleRole getAccessibleRole() {
  987. return AccessibleRole.LABEL;
  988. }
  989. /**
  990. * Get the AccessibleIcons associated with this object if one
  991. * or more exist. Otherwise return null.
  992. */
  993. public AccessibleIcon [] getAccessibleIcon() {
  994. if (JLabel.this.accessibleIcon == null) {
  995. return null;
  996. } else {
  997. AccessibleIcon [] ac = new AccessibleIcon[1];
  998. ac[0] = JLabel.this.accessibleIcon;
  999. return ac;
  1000. }
  1001. }
  1002. /**
  1003. * Get the AccessibleRelationSet associated with this object if one
  1004. * exists. Otherwise return null.
  1005. * @see AccessibleRelation
  1006. */
  1007. public AccessibleRelationSet getAccessibleRelationSet() {
  1008. // Check where the AccessibleContext's relation
  1009. // set already contains a LABEL_FOR relation.
  1010. AccessibleRelationSet relationSet
  1011. = super.getAccessibleRelationSet();
  1012. if (!relationSet.contains(AccessibleRelation.LABEL_FOR)) {
  1013. Component c = JLabel.this.getLabelFor();
  1014. if (c != null) {
  1015. AccessibleRelation relation
  1016. = new AccessibleRelation(AccessibleRelation.LABEL_FOR);
  1017. relation.setTarget(c);
  1018. relationSet.add(relation);
  1019. }
  1020. }
  1021. return relationSet;
  1022. }
  1023. /* AccessibleText ---------- */
  1024. public AccessibleText getAccessibleText() {
  1025. View view = (View)JLabel.this.getClientProperty("html");
  1026. if (view != null) {
  1027. return this;
  1028. } else {
  1029. return null;
  1030. }
  1031. }
  1032. /**
  1033. * Given a point in local coordinates, return the zero-based index
  1034. * of the character under that Point. If the point is invalid,
  1035. * this method returns -1.
  1036. *
  1037. * @param p the Point in local coordinates
  1038. * @return the zero-based index of the character under Point p; if
  1039. * Point is invalid returns -1.
  1040. */
  1041. public int getIndexAtPoint(Point p) {
  1042. View view = (View) JLabel.this.getClientProperty("html");
  1043. if (view != null) {
  1044. Rectangle r = getTextRectangle();
  1045. if (r == null) {
  1046. return -1;
  1047. }
  1048. Rectangle2D.Float shape =
  1049. new Rectangle2D.Float(r.x, r.y, r.width, r.height);
  1050. Position.Bias bias[] = new Position.Bias[1];
  1051. return view.viewToModel(p.x, p.y, shape, bias);
  1052. } else {
  1053. return -1;
  1054. }
  1055. }
  1056. /**
  1057. * Determine the bounding box of the character at the given
  1058. * index into the string. The bounds are returned in local
  1059. * coordinates. If the index is invalid an empty rectangle is
  1060. * returned.
  1061. *
  1062. * @param i the index into the String
  1063. * @return the screen coordinates of the character's the bounding box,
  1064. * if index is invalid returns an empty rectangle.
  1065. */
  1066. public Rectangle getCharacterBounds(int i) {
  1067. View view = (View) JLabel.this.getClientProperty("html");
  1068. if (view != null) {
  1069. Rectangle r = getTextRectangle();
  1070. if (r == null) {
  1071. return null;
  1072. }
  1073. Rectangle2D.Float shape =
  1074. new Rectangle2D.Float(r.x, r.y, r.width, r.height);
  1075. try {
  1076. Shape charShape =
  1077. view.modelToView(i, shape, Position.Bias.Forward);
  1078. return charShape.getBounds();
  1079. } catch (BadLocationException e) {
  1080. return null;
  1081. }
  1082. } else {
  1083. return null;
  1084. }
  1085. }
  1086. /**
  1087. * Return the number of characters (valid indicies)
  1088. *
  1089. * @return the number of characters
  1090. */
  1091. public int getCharCount() {
  1092. View view = (View) JLabel.this.getClientProperty("html");
  1093. if (view != null) {
  1094. Document d = view.getDocument();
  1095. if (d instanceof StyledDocument) {
  1096. StyledDocument doc = (StyledDocument)d;
  1097. return doc.getLength();
  1098. }
  1099. }
  1100. return accessibleContext.getAccessibleName().length();
  1101. }
  1102. /**
  1103. * Return the zero-based offset of the caret.
  1104. *
  1105. * Note: That to the right of the caret will have the same index
  1106. * value as the offset (the caret is between two characters).
  1107. * @return the zero-based offset of the caret.
  1108. */
  1109. public int getCaretPosition() {
  1110. // There is no caret.
  1111. return -1;
  1112. }
  1113. /**
  1114. * Returns the String at a given index.
  1115. *
  1116. * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
  1117. * or AccessibleText.SENTENCE to retrieve
  1118. * @param index an index within the text >= 0
  1119. * @return the letter, word, or sentence,
  1120. * null for an invalid index or part
  1121. */
  1122. public String getAtIndex(int part, int index) {
  1123. if (index < 0 || index >= getCharCount()) {
  1124. return null;
  1125. }
  1126. switch (part) {
  1127. case AccessibleText.CHARACTER:
  1128. try {
  1129. return getText(index, 1);
  1130. } catch (BadLocationException e) {
  1131. return null;
  1132. }
  1133. case AccessibleText.WORD:
  1134. try {
  1135. String s = getText(0, getCharCount());
  1136. BreakIterator words = BreakIterator.getWordInstance(getLocale());
  1137. words.setText(s);
  1138. int end = words.following(index);
  1139. return s.substring(words.previous(), end);
  1140. } catch (BadLocationException e) {
  1141. return null;
  1142. }
  1143. case AccessibleText.SENTENCE:
  1144. try {
  1145. String s = getText(0, getCharCount());
  1146. BreakIterator sentence =
  1147. BreakIterator.getSentenceInstance(getLocale());
  1148. sentence.setText(s);
  1149. int end = sentence.following(index);
  1150. return s.substring(sentence.previous(), end);
  1151. } catch (BadLocationException e) {
  1152. return null;
  1153. }
  1154. default:
  1155. return null;
  1156. }
  1157. }
  1158. /**
  1159. * Returns the String after a given index.
  1160. *
  1161. * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
  1162. * or AccessibleText.SENTENCE to retrieve
  1163. * @param index an index within the text >= 0
  1164. * @return the letter, word, or sentence, null for an invalid
  1165. * index or part
  1166. */
  1167. public String getAfterIndex(int part, int index) {
  1168. if (index < 0 || index >= getCharCount()) {
  1169. return null;
  1170. }
  1171. switch (part) {
  1172. case AccessibleText.CHARACTER:
  1173. if (index+1 >= getCharCount()) {
  1174. return null;
  1175. }
  1176. try {
  1177. return getText(index+1, 1);
  1178. } catch (BadLocationException e) {
  1179. return null;
  1180. }
  1181. case AccessibleText.WORD:
  1182. try {
  1183. String s = getText(0, getCharCount());
  1184. BreakIterator words = BreakIterator.getWordInstance(getLocale());
  1185. words.setText(s);
  1186. int start = words.following(index);
  1187. if (start == BreakIterator.DONE || start >= s.length()) {
  1188. return null;
  1189. }
  1190. int end = words.following(start);
  1191. if (end == BreakIterator.DONE || end >= s.length()) {
  1192. return null;
  1193. }
  1194. return s.substring(start, end);
  1195. } catch (BadLocationException e) {
  1196. return null;
  1197. }
  1198. case AccessibleText.SENTENCE:
  1199. try {
  1200. String s = getText(0, getCharCount());
  1201. BreakIterator sentence =
  1202. BreakIterator.getSentenceInstance(getLocale());
  1203. sentence.setText(s);
  1204. int start = sentence.following(index);
  1205. if (start == BreakIterator.DONE || start >= s.length()) {
  1206. return null;
  1207. }
  1208. int end = sentence.following(start);
  1209. if (end == BreakIterator.DONE || end >= s.length()) {
  1210. return null;
  1211. }
  1212. return s.substring(start, end);
  1213. } catch (BadLocationException e) {
  1214. return null;
  1215. }
  1216. default:
  1217. return null;
  1218. }
  1219. }
  1220. /**
  1221. * Returns the String before a given index.
  1222. *
  1223. * @param part the AccessibleText.CHARACTER, AccessibleText.WORD,
  1224. * or AccessibleText.SENTENCE to retrieve
  1225. * @param index an index within the text >= 0
  1226. * @return the letter, word, or sentence, null for an invalid index
  1227. * or part
  1228. */
  1229. public String getBeforeIndex(int part, int index) {
  1230. if (index < 0 || index > getCharCount()-1) {
  1231. return null;
  1232. }
  1233. switch (part) {
  1234. case AccessibleText.CHARACTER:
  1235. if (index == 0) {
  1236. return null;
  1237. }
  1238. try {
  1239. return getText(index-1, 1);
  1240. } catch (BadLocationException e) {
  1241. return null;
  1242. }
  1243. case AccessibleText.WORD:
  1244. try {
  1245. String s = getText(0, getCharCount());
  1246. BreakIterator words = BreakIterator.getWordInstance(getLocale());
  1247. words.setText(s);
  1248. int end = words.following(index);
  1249. end = words.previous();
  1250. int start = words.previous();
  1251. if (start == BreakIterator.DONE) {
  1252. return null;
  1253. }
  1254. return s.substring(start, end);
  1255. } catch (BadLocationException e) {
  1256. return null;
  1257. }
  1258. case AccessibleText.SENTENCE:
  1259. try {
  1260. String s = getText(0, getCharCount());
  1261. BreakIterator sentence =
  1262. BreakIterator.getSentenceInstance(getLocale());
  1263. sentence.setText(s);
  1264. int end = sentence.following(index);
  1265. end = sentence.previous();
  1266. int start = sentence.previous();
  1267. if (start == BreakIterator.DONE) {
  1268. return null;
  1269. }
  1270. return s.substring(start, end);
  1271. } catch (BadLocationException e) {
  1272. return null;
  1273. }
  1274. default:
  1275. return null;
  1276. }
  1277. }
  1278. /**
  1279. * Return the AttributeSet for a given character at a given index
  1280. *
  1281. * @param i the zero-based index into the text
  1282. * @return the AttributeSet of the character
  1283. */
  1284. public AttributeSet getCharacterAttribute(int i) {
  1285. View view = (View) JLabel.this.getClientProperty("html");
  1286. if (view != null) {
  1287. Document d = view.getDocument();
  1288. if (d instanceof StyledDocument) {
  1289. StyledDocument doc = (StyledDocument)d;
  1290. Element elem = doc.getCharacterElement(i);
  1291. if (elem != null) {
  1292. return elem.getAttributes();
  1293. }
  1294. }
  1295. }
  1296. return null;
  1297. }
  1298. /**
  1299. * Returns the start offset within the selected text.
  1300. * If there is no selection, but there is
  1301. * a caret, the start and end offsets will be the same.
  1302. *
  1303. * @return the index into the text of the start of the selection
  1304. */
  1305. public int getSelectionStart() {
  1306. // Text cannot be selected.
  1307. return -1;
  1308. }
  1309. /**
  1310. * Returns the end offset within the selected text.
  1311. * If there is no selection, but there is
  1312. * a caret, the start and end offsets will be the same.
  1313. *
  1314. * @return the index into teh text of the end of the selection
  1315. */
  1316. public int getSelectionEnd() {
  1317. // Text cannot be selected.
  1318. return -1;
  1319. }
  1320. /**
  1321. * Returns the portion of the text that is selected.
  1322. *
  1323. * @return the String portion of the text that is selected
  1324. */
  1325. public String getSelectedText() {
  1326. // Text cannot be selected.
  1327. return null;
  1328. }
  1329. /*
  1330. * Returns the text substring starting at the specified
  1331. * offset with the specified length.
  1332. */
  1333. private String getText(int offset, int length)
  1334. throws BadLocationException {
  1335. View view = (View) JLabel.this.getClientProperty("html");
  1336. if (view != null) {
  1337. Document d = view.getDocument();
  1338. if (d instanceof StyledDocument) {
  1339. StyledDocument doc = (StyledDocument)d;
  1340. return doc.getText(offset, length);
  1341. }
  1342. }
  1343. return null;
  1344. }
  1345. /*
  1346. * Returns the bounding rectangle for the component text.
  1347. */
  1348. private Rectangle getTextRectangle() {
  1349. String text = JLabel.this.getText();
  1350. Icon icon = (JLabel.this.isEnabled()) ? JLabel.this.getIcon() : JLabel.this.getDisabledIcon();
  1351. if ((icon == null) && (text == null)) {
  1352. return null;
  1353. }
  1354. Rectangle paintIconR = new Rectangle();
  1355. Rectangle paintTextR = new Rectangle();
  1356. Rectangle paintViewR = new Rectangle();
  1357. Insets paintViewInsets = new Insets(0, 0, 0, 0);
  1358. paintViewInsets = JLabel.this.getInsets(paintViewInsets);
  1359. paintViewR.x = paintViewInsets.left;
  1360. paintViewR.y = paintViewInsets.top;
  1361. paintViewR.width = JLabel.this.getWidth() - (paintViewInsets.left + paintViewInsets.right);
  1362. paintViewR.height = JLabel.this.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
  1363. Graphics g = JLabel.this.getGraphics();
  1364. if (g == null) {
  1365. return null;
  1366. }
  1367. String clippedText = SwingUtilities.layoutCompoundLabel(
  1368. (JComponent)JLabel.this,
  1369. g.getFontMetrics(),
  1370. text,
  1371. icon,
  1372. JLabel.this.getVerticalAlignment(),
  1373. JLabel.this.getHorizontalAlignment(),
  1374. JLabel.this.getVerticalTextPosition(),
  1375. JLabel.this.getHorizontalTextPosition(),
  1376. paintViewR,
  1377. paintIconR,
  1378. paintTextR,
  1379. JLabel.this.getIconTextGap());
  1380. return paintTextR;
  1381. }
  1382. // ----- AccessibleExtendedComponent
  1383. /**
  1384. * Returns the AccessibleExtendedComponent
  1385. *
  1386. * @return the AccessibleExtendedComponent
  1387. */
  1388. AccessibleExtendedComponent getAccessibleExtendedComponent() {
  1389. return this;
  1390. }
  1391. /**
  1392. * Returns the tool tip text
  1393. *
  1394. * @return the tool tip text, if supported, of the object;
  1395. * otherwise, null
  1396. */
  1397. public String getToolTipText() {
  1398. return JLabel.this.getToolTipText();
  1399. }
  1400. /**
  1401. * Returns the titled border text
  1402. *
  1403. * @return the titled border text, if supported, of the object;
  1404. * otherwise, null
  1405. */
  1406. public String getTitledBorderText() {
  1407. return super.getTitledBorderText();
  1408. }
  1409. /**
  1410. * Returns key bindings associated with this object
  1411. *
  1412. * @return the key bindings, if supported, of the object;
  1413. * otherwise, null
  1414. * @see AccessibleKeyBinding
  1415. */
  1416. public AccessibleKeyBinding getAccessibleKeyBinding() {
  1417. int mnemonic = JLabel.this.getDisplayedMnemonic();
  1418. if (mnemonic == 0) {
  1419. return null;
  1420. }
  1421. return new LabelKeyBinding(mnemonic);
  1422. }
  1423. class LabelKeyBinding implements AccessibleKeyBinding {
  1424. int mnemonic;
  1425. LabelKeyBinding(int mnemonic) {
  1426. this.mnemonic = mnemonic;
  1427. }
  1428. /**
  1429. * Returns the number of key bindings for this object
  1430. *
  1431. * @return the zero-based number of key bindings for this object
  1432. */
  1433. public int getAccessibleKeyBindingCount() {
  1434. return 1;
  1435. }
  1436. /**
  1437. * Returns a key binding for this object. The value returned is an
  1438. * java.lang.Object which must be cast to appropriate type depending
  1439. * on the underlying implementation of the key. For example, if the
  1440. * Object returned is a javax.swing.KeyStroke, the user of this
  1441. * method should do the following:
  1442. * <nf><code>
  1443. * Component c = <get the component that has the key bindings>
  1444. * AccessibleContext ac = c.getAccessibleContext();
  1445. * AccessibleKeyBinding akb = ac.getAccessibleKeyBinding();
  1446. * for (int i = 0; i < akb.getAccessibleKeyBindingCount(); i++) {
  1447. * Object o = akb.getAccessibleKeyBinding(i);
  1448. * if (o instanceof javax.swing.KeyStroke) {
  1449. * javax.swing.KeyStroke keyStroke = (javax.swing.KeyStroke)o;
  1450. * <do something with the key binding>
  1451. * }
  1452. * }
  1453. * </code></nf>
  1454. *
  1455. * @param i zero-based index of the key bindings
  1456. * @return a javax.lang.Object which specifies the key binding
  1457. * @exception IllegalArgumentException if the index is
  1458. * out of bounds
  1459. * @see #getAccessibleKeyBindingCount
  1460. */
  1461. public java.lang.Object getAccessibleKeyBinding(int i) {
  1462. if (i != 0) {
  1463. throw new IllegalArgumentException();
  1464. }
  1465. return KeyStroke.getKeyStroke(mnemonic, 0);
  1466. }
  1467. }
  1468. } // AccessibleJComponent
  1469. }