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