GNU Classpath (0.95) | |
Frames | No Frames |
1: /* JLabel.java -- 2: Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Component; 42: import java.awt.Font; 43: import java.awt.FontMetrics; 44: import java.awt.Image; 45: import java.awt.Insets; 46: import java.awt.Point; 47: import java.awt.Rectangle; 48: import java.awt.Shape; 49: import java.awt.event.KeyEvent; 50: import java.beans.PropertyChangeEvent; 51: 52: import javax.accessibility.Accessible; 53: import javax.accessibility.AccessibleContext; 54: import javax.accessibility.AccessibleExtendedComponent; 55: import javax.accessibility.AccessibleRole; 56: import javax.accessibility.AccessibleText; 57: import javax.swing.plaf.LabelUI; 58: import javax.swing.plaf.basic.BasicHTML; 59: import javax.swing.text.AttributeSet; 60: import javax.swing.text.BadLocationException; 61: import javax.swing.text.Position; 62: import javax.swing.text.SimpleAttributeSet; 63: import javax.swing.text.View; 64: 65: /** 66: * A component that displays a static text message and/or an icon. 67: */ 68: public class JLabel extends JComponent implements Accessible, SwingConstants 69: { 70: 71: /** 72: * Provides the accessibility features for the <code>JLabel</code> 73: * component. 74: */ 75: protected class AccessibleJLabel 76: extends JComponent.AccessibleJComponent 77: implements AccessibleText, AccessibleExtendedComponent 78: { 79: 80: /** 81: * Returns the accessible name. 82: * 83: * @return The accessible name. 84: */ 85: public String getAccessibleName() 86: { 87: if (accessibleName != null) 88: return accessibleName; 89: if (text != null) 90: return text; 91: else 92: return super.getAccessibleName(); 93: } 94: 95: /** 96: * Returns the accessible role for the <code>JLabel</code> component. 97: * 98: * @return {@link AccessibleRole#LABEL}. 99: */ 100: public AccessibleRole getAccessibleRole() 101: { 102: return AccessibleRole.LABEL; 103: } 104: 105: /** 106: * Returns the selected text. This is null since JLabels 107: * are not selectable. 108: * 109: * @return <code>null</code> because JLabels cannot have selected text 110: */ 111: public String getSelectedText() 112: { 113: // We return null here since JLabel's text is not selectable. 114: return null; 115: } 116: 117: /** 118: * Returns the start index of the selected text. 119: * 120: * @return the start index of the selected text 121: */ 122: public int getSelectionStart() 123: { 124: // JLabel don't have selected text, so we return -1 here. 125: return -1; 126: } 127: 128: /** 129: * Returns the end index of the selected text. 130: * 131: * @return the end index of the selected text 132: */ 133: public int getSelectionEnd() 134: { 135: // JLabel don't have selected text, so we return -1 here. 136: return -1; 137: } 138: 139: /** 140: * Returns an {@link AttributeSet} that reflects the text attributes of 141: * the specified character. We return an empty 142: * <code>AttributeSet</code> here, because JLabels don't support text 143: * attributes (at least not yet). 144: * 145: * @param index the index of the character 146: * 147: * @return an {@link AttributeSet} that reflects the text attributes of 148: * the specified character 149: */ 150: public AttributeSet getCharacterAttribute(int index) 151: { 152: // FIXME: Return null here for simple labels, and query the HTML 153: // view for HTML labels. 154: return new SimpleAttributeSet(); 155: } 156: 157: /** 158: * Returns the character, word or sentence at the specified index. The 159: * <code>part</code> parameter determines what is returned, the character, 160: * word or sentence after the index. 161: * 162: * @param part one of {@link AccessibleText#CHARACTER}, 163: * {@link AccessibleText#WORD} or 164: * {@link AccessibleText#SENTENCE}, specifying what is returned 165: * @param index the index 166: * 167: * @return the character, word or sentence after <code>index</code> 168: */ 169: public String getAtIndex(int part, int index) 170: { 171: String result = ""; 172: int startIndex = -1; 173: int endIndex = -1; 174: switch(part) 175: { 176: case AccessibleText.CHARACTER: 177: result = String.valueOf(text.charAt(index)); 178: break; 179: case AccessibleText.WORD: 180: startIndex = text.lastIndexOf(' ', index); 181: endIndex = text.indexOf(' ', startIndex + 1); 182: if (endIndex == -1) 183: endIndex = startIndex + 1; 184: result = text.substring(startIndex + 1, endIndex); 185: break; 186: case AccessibleText.SENTENCE: 187: default: 188: startIndex = text.lastIndexOf('.', index); 189: endIndex = text.indexOf('.', startIndex + 1); 190: if (endIndex == -1) 191: endIndex = startIndex + 1; 192: result = text.substring(startIndex + 1, endIndex); 193: break; 194: } 195: return result; 196: } 197: 198: /** 199: * Returns the character, word or sentence after the specified index. The 200: * <code>part</code> parameter determines what is returned, the character, 201: * word or sentence after the index. 202: * 203: * @param part one of {@link AccessibleText#CHARACTER}, 204: * {@link AccessibleText#WORD} or 205: * {@link AccessibleText#SENTENCE}, specifying what is returned 206: * @param index the index 207: * 208: * @return the character, word or sentence after <code>index</code> 209: */ 210: public String getAfterIndex(int part, int index) 211: { 212: String result = ""; 213: int startIndex = -1; 214: int endIndex = -1; 215: switch(part) 216: { 217: case AccessibleText.CHARACTER: 218: result = String.valueOf(text.charAt(index + 1)); 219: break; 220: case AccessibleText.WORD: 221: startIndex = text.indexOf(' ', index); 222: endIndex = text.indexOf(' ', startIndex + 1); 223: if (endIndex == -1) 224: endIndex = startIndex + 1; 225: result = text.substring(startIndex + 1, endIndex); 226: break; 227: case AccessibleText.SENTENCE: 228: default: 229: startIndex = text.indexOf('.', index); 230: endIndex = text.indexOf('.', startIndex + 1); 231: if (endIndex == -1) 232: endIndex = startIndex + 1; 233: result = text.substring(startIndex + 1, endIndex); 234: break; 235: } 236: return result; 237: } 238: 239: /** 240: * Returns the character, word or sentence before the specified index. The 241: * <code>part</code> parameter determines what is returned, the character, 242: * word or sentence before the index. 243: * 244: * @param part one of {@link AccessibleText#CHARACTER}, 245: * {@link AccessibleText#WORD} or 246: * {@link AccessibleText#SENTENCE}, specifying what is returned 247: * @param index the index 248: * 249: * @return the character, word or sentence before <code>index</code> 250: */ 251: public String getBeforeIndex(int part, int index) 252: { 253: String result = ""; 254: int startIndex = -1; 255: int endIndex = -1; 256: switch(part) 257: { 258: case AccessibleText.CHARACTER: 259: result = String.valueOf(text.charAt(index - 1)); 260: break; 261: case AccessibleText.WORD: 262: endIndex = text.lastIndexOf(' ', index); 263: if (endIndex == -1) 264: endIndex = 0; 265: startIndex = text.lastIndexOf(' ', endIndex - 1); 266: result = text.substring(startIndex + 1, endIndex); 267: break; 268: case AccessibleText.SENTENCE: 269: default: 270: endIndex = text.lastIndexOf('.', index); 271: if (endIndex == -1) 272: endIndex = 0; 273: startIndex = text.lastIndexOf('.', endIndex - 1); 274: result = text.substring(startIndex + 1, endIndex); 275: break; 276: } 277: return result; 278: } 279: 280: /** 281: * Returns the caret position. This method returns -1 because JLabel don't 282: * have a caret. 283: * 284: * @return the caret position 285: */ 286: public int getCaretPosition() 287: { 288: return -1; 289: } 290: 291: /** 292: * Returns the number of characters that are displayed by the JLabel. 293: * 294: * @return the number of characters that are displayed by the JLabel 295: */ 296: public int getCharCount() 297: { 298: // FIXME: Query HTML view for HTML labels. 299: return text.length(); 300: } 301: 302: /** 303: * Returns the bounding box of the character at the specified index. 304: * 305: * @param index the index of the character that we return the 306: * bounds for 307: * 308: * @return the bounding box of the character at the specified index 309: */ 310: public Rectangle getCharacterBounds(int index) 311: { 312: Rectangle bounds = null; 313: View view = (View) getClientProperty(BasicHTML.propertyKey); 314: if (view != null) 315: { 316: Rectangle textR = getTextRectangle(); 317: try 318: { 319: Shape s = view.modelToView(index, textR, Position.Bias.Forward); 320: bounds = s.getBounds(); 321: } 322: catch (BadLocationException ex) 323: { 324: // Can't return something reasonable in this case. 325: } 326: } 327: return bounds; 328: } 329: 330: /** 331: * Returns the rectangle inside the JLabel, in which the actual text is 332: * rendered. This method has been adopted from the Mauve testcase 333: * gnu.testlet.javax.swing.JLabel.AccessibleJLabel.getCharacterBounds. 334: * 335: * @return the rectangle inside the JLabel, in which the actual text is 336: * rendered 337: */ 338: private Rectangle getTextRectangle() 339: { 340: JLabel l = JLabel.this; 341: Rectangle textR = new Rectangle(); 342: Rectangle iconR = new Rectangle(); 343: Insets i = l.getInsets(); 344: int w = l.getWidth(); 345: int h = l.getHeight(); 346: Rectangle viewR = new Rectangle(i.left, i.top, w - i.left - i.right, 347: h - i.top - i.bottom); 348: FontMetrics fm = l.getFontMetrics(l.getFont()); 349: SwingUtilities.layoutCompoundLabel(l, fm, l.getText(), l.getIcon(), 350: l.getVerticalAlignment(), 351: l.getHorizontalAlignment(), 352: l.getVerticalTextPosition(), 353: l.getHorizontalTextPosition(), 354: viewR, iconR, textR, 355: l.getIconTextGap()); 356: return textR; 357: } 358: 359: /** 360: * Returns the index of the character that is located at the specified 361: * point. 362: * 363: * @param point the location that we lookup the character for 364: * 365: * @return the index of the character that is located at the specified 366: * point 367: */ 368: public int getIndexAtPoint(Point point) 369: { 370: int index = -1; 371: View view = (View) getClientProperty(BasicHTML.propertyKey); 372: if (view != null) 373: { 374: Rectangle r = getTextRectangle(); 375: index = view.viewToModel(point.x, point.y, r, new Position.Bias[0]); 376: } 377: return index; 378: } 379: } 380: 381: private static final long serialVersionUID = 5496508283662221534L; 382: 383: static final String LABEL_PROPERTY = "labeledBy"; 384: 385: /** 386: * The Component the label will give focus to when its mnemonic is 387: * activated. 388: */ 389: protected Component labelFor; 390: 391: /** The label's text. */ 392: transient String text; 393: 394: /** Where the label will be positioned horizontally. */ 395: private transient int horizontalAlignment = LEADING; 396: 397: /** Where the label text will be placed horizontally relative to the icon. */ 398: private transient int horizontalTextPosition = TRAILING; 399: 400: /** Where the label will be positioned vertically. */ 401: private transient int verticalAlignment = CENTER; 402: 403: /** Where the label text will be place vertically relative to the icon. */ 404: private transient int verticalTextPosition = CENTER; 405: 406: /** The icon painted when the label is enabled. */ 407: private transient Icon icon; 408: 409: /** The icon painted when the label is disabled. */ 410: private transient Icon disabledIcon; 411: 412: /** The label's mnemnonic key. */ 413: private transient int displayedMnemonic = KeyEvent.VK_UNDEFINED; 414: 415: /** The index of the mnemonic character in the text. */ 416: private transient int displayedMnemonicIndex = -1; 417: 418: /** The gap between the icon and the text. */ 419: private transient int iconTextGap = 4; 420: 421: /** 422: * Creates a new vertically centered, horizontally on the leading edge 423: * JLabel object with text and no icon. 424: */ 425: public JLabel() 426: { 427: this("", null, LEADING); 428: } 429: 430: /** 431: * Creates a new vertically and horizontally centered 432: * JLabel object with no text and the given icon. 433: * 434: * @param image The icon to use with the label, <code>null</code> permitted. 435: */ 436: public JLabel(Icon image) 437: { 438: this(null, image, CENTER); 439: } 440: 441: /** 442: * Creates a new vertically centered JLabel object with no text and the 443: * given icon and horizontal alignment. By default, the text is TRAILING 444: * the image. 445: * 446: * @param image The icon to use with the label, <code>null</code> premitted. 447: * @param horizontalAlignment The horizontal alignment of the label, must be 448: * either <code>CENTER</code>, <code>LEFT</code>, <code>RIGHT</code>, 449: * <code>LEADING</code> or <code>TRAILING</code>. 450: */ 451: public JLabel(Icon image, int horizontalAlignment) 452: { 453: this(null, image, horizontalAlignment); 454: } 455: 456: /** 457: * Creates a new horizontally leading and vertically centered JLabel 458: * object with no icon and the given text. 459: * 460: * @param text The text to use with the label, <code>null</code> permitted. 461: */ 462: public JLabel(String text) 463: { 464: this(text, null, LEADING); 465: } 466: 467: /** 468: * Creates a new vertically centered JLabel object with no icon and the 469: * given text and horizontal alignment. 470: * 471: * @param text The text to use with the label, <code>null</code> permitted. 472: * @param horizontalAlignment The horizontal alignment of the label, must be 473: * either <code>CENTER</code>, <code>LEFT</code>, <code>RIGHT</code>, 474: * <code>LEADING</code> or <code>TRAILING</code>. 475: */ 476: public JLabel(String text, int horizontalAlignment) 477: { 478: this(text, null, horizontalAlignment); 479: } 480: 481: /** 482: * Creates a new vertically centered JLabel object with the given text, 483: * icon, and horizontal alignment. 484: * 485: * @param text The text to use with the label, <code>null</code> permitted. 486: * @param icon The icon to use with the label, <code>null</code> premitted. 487: * @param horizontalAlignment The horizontal alignment of the label, must be 488: * either <code>CENTER</code>, <code>LEFT</code>, <code>RIGHT</code>, 489: * <code>LEADING</code> or <code>TRAILING</code>. 490: */ 491: public JLabel(String text, Icon icon, int horizontalAlignment) 492: { 493: if (horizontalAlignment != SwingConstants.LEFT 494: && horizontalAlignment != SwingConstants.RIGHT 495: && horizontalAlignment != SwingConstants.CENTER 496: && horizontalAlignment != SwingConstants.LEADING 497: && horizontalAlignment != SwingConstants.TRAILING) 498: throw new IllegalArgumentException(); 499: 500: this.text = text; 501: this.icon = icon; 502: this.horizontalAlignment = horizontalAlignment; 503: setAlignmentX(0.0F); 504: setInheritsPopupMenu(true); 505: updateUI(); 506: } 507: 508: /** 509: * Returns the label's UI delegate. 510: * 511: * @return The label's UI delegate. 512: */ 513: public LabelUI getUI() 514: { 515: return (LabelUI) ui; 516: } 517: 518: /** 519: * Sets the label's UI delegate. 520: * 521: * @param ui The label's UI delegate (<code>null</code> not permitted). 522: */ 523: public void setUI(LabelUI ui) 524: { 525: super.setUI(ui); 526: } 527: 528: /** 529: * Resets the label's UI delegate to the default UI for the current look and 530: * feel. 531: */ 532: public void updateUI() 533: { 534: setUI((LabelUI) UIManager.getUI(this)); 535: } 536: 537: /** 538: * Returns a name to identify which look and feel class will be 539: * the UI delegate for this label. 540: * 541: * @return <code>"LabelUI"</code> 542: */ 543: public String getUIClassID() 544: { 545: return "LabelUI"; 546: } 547: 548: /** 549: * Returns a string describing the attributes for the <code>JLabel</code> 550: * component, for use in debugging. The return value is guaranteed to be 551: * non-<code>null</code>, but the format of the string may vary between 552: * implementations. 553: * 554: * @return A string describing the attributes of the <code>JLabel</code>. 555: */ 556: protected String paramString() 557: { 558: StringBuffer sb = new StringBuffer(super.paramString()); 559: sb.append(",defaultIcon="); 560: if (icon != null) 561: sb.append(icon); 562: sb.append(",disabledIcon="); 563: if (disabledIcon != null) 564: sb.append(disabledIcon); 565: sb.append(",horizontalAlignment="); 566: sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString( 567: horizontalAlignment)); 568: sb.append(",horizontalTextPosition="); 569: sb.append(SwingUtilities.convertHorizontalAlignmentCodeToString( 570: horizontalTextPosition)); 571: sb.append(",iconTextGap=").append(iconTextGap); 572: sb.append(",labelFor="); 573: if (labelFor != null) 574: sb.append(labelFor); 575: sb.append(",text="); 576: if (text != null) 577: sb.append(text); 578: sb.append(",verticalAlignment="); 579: sb.append(SwingUtilities.convertVerticalAlignmentCodeToString( 580: verticalAlignment)); 581: sb.append(",verticalTextPosition="); 582: sb.append(SwingUtilities.convertVerticalAlignmentCodeToString( 583: verticalTextPosition)); 584: return sb.toString(); 585: } 586: 587: /** 588: * Returns the text displayed by the label. 589: * 590: * @return The label text (possibly <code>null</code>). 591: * 592: * @see #setText(String) 593: */ 594: public String getText() 595: { 596: return text; 597: } 598: 599: /** 600: * Sets the text for the label and sends a {@link PropertyChangeEvent} (with 601: * the name 'text') to all registered listeners. This method will also 602: * update the <code>displayedMnemonicIndex</code>, if necessary. 603: * 604: * @param newText The text (<code>null</code> permitted). 605: * 606: * @see #getText() 607: * @see #getDisplayedMnemonicIndex() 608: */ 609: public void setText(String newText) 610: { 611: if (text == null && newText == null) 612: return; 613: if (text != null && text.equals(newText)) 614: return; 615: 616: String oldText = text; 617: text = newText; 618: firePropertyChange("text", oldText, newText); 619: 620: if (text != null) 621: setDisplayedMnemonicIndex(text.toUpperCase().indexOf(displayedMnemonic)); 622: else 623: setDisplayedMnemonicIndex(-1); 624: revalidate(); 625: repaint(); 626: } 627: 628: /** 629: * Returns the active icon. The active icon is painted when the label is 630: * enabled. 631: * 632: * @return The active icon. 633: * 634: * @see #setIcon(Icon) 635: * @see #getDisabledIcon() 636: */ 637: public Icon getIcon() 638: { 639: return icon; 640: } 641: 642: /** 643: * Sets the icon for the label (this is a bound property with the name 644: * 'icon'). This icon will be displayed when the label is enabled. 645: * 646: * @param newIcon The icon (<code>null</code> permitted). 647: * 648: * @see #getIcon() 649: * @see #setDisabledIcon(Icon) 650: */ 651: public void setIcon(Icon newIcon) 652: { 653: if (icon != newIcon) 654: { 655: Icon oldIcon = icon; 656: icon = newIcon; 657: firePropertyChange("icon", oldIcon, newIcon); 658: repaint(); 659: } 660: } 661: 662: /** 663: * Returns the disabled icon. The disabled icon is painted when the label is 664: * disabled. If the disabled icon is <code>null</code> and the active icon 665: * is an {@link ImageIcon}, this method returns a grayed version of the icon. 666: * The grayed version of the icon becomes the <code>disabledIcon</code>. 667: * 668: * @return The disabled icon. 669: * 670: * @see #setDisabledIcon(Icon) 671: */ 672: public Icon getDisabledIcon() 673: { 674: if (disabledIcon == null && icon instanceof ImageIcon) 675: disabledIcon = new ImageIcon( 676: GrayFilter.createDisabledImage(((ImageIcon) icon).getImage())); 677: 678: return disabledIcon; 679: } 680: 681: /** 682: * Sets the icon displayed when the label is disabled (this is a bound 683: * property with the name 'disabledIcon'). 684: * 685: * @param newIcon The disabled icon (<code>null</code> permitted). 686: * 687: * @see #getDisabledIcon() 688: */ 689: public void setDisabledIcon(Icon newIcon) 690: { 691: if (disabledIcon != newIcon) 692: { 693: Icon oldIcon = disabledIcon; 694: disabledIcon = newIcon; 695: firePropertyChange("disabledIcon", oldIcon, newIcon); 696: } 697: } 698: 699: /** 700: * Sets the keycode that will be the label's mnemonic (this is a bound 701: * property with the name 'displayedMnemonic'). If the label is used as a 702: * label for another component, the label will give focus to that component 703: * when the mnemonic is activated. 704: * 705: * @param mnemonic The keycode to use for the mnemonic. 706: * 707: * @see #getDisplayedMnemonic() 708: */ 709: public void setDisplayedMnemonic(int mnemonic) 710: { 711: if (displayedMnemonic != mnemonic) 712: { 713: int old = displayedMnemonic; 714: displayedMnemonic = mnemonic; 715: firePropertyChange("displayedMnemonic", old, displayedMnemonic); 716: if (text != null) 717: setDisplayedMnemonicIndex(text.toUpperCase().indexOf(mnemonic)); 718: } 719: } 720: 721: /** 722: * Sets the character that will be the label's mnemonic. If the 723: * label is used as a label for another component, the label will give 724: * focus to that component when the mnemonic is activated via the keyboard. 725: * 726: * @param mnemonic The character to use for the mnemonic (this will be 727: * converted to the equivalent upper case character). 728: * 729: * @see #getDisplayedMnemonic() 730: */ 731: public void setDisplayedMnemonic(char mnemonic) 732: { 733: setDisplayedMnemonic((int) Character.toUpperCase(mnemonic)); 734: } 735: 736: /** 737: * Returns the keycode that is used for the label's mnemonic. 738: * 739: * @return The keycode that is used for the label's mnemonic. 740: * 741: * @see #setDisplayedMnemonic(int) 742: */ 743: public int getDisplayedMnemonic() 744: { 745: return displayedMnemonic; 746: } 747: 748: /** 749: * Sets the index of the character in the text that will be underlined to 750: * indicate that it is the mnemonic character for the label. You only need 751: * to call this method if you wish to override the automatically calculated 752: * character index. For instance, for a label "Find Next" with the mnemonic 753: * character 'n', you might wish to underline the second occurrence of 'n' 754: * rather than the first (which is the default). 755: * <br><br> 756: * Note that this method does not validate the character at the specified 757: * index to ensure that it matches the key code returned by 758: * {@link #getDisplayedMnemonic()}. 759: * 760: * @param newIndex The index of the character to underline. 761: * 762: * @throws IllegalArgumentException If index less than -1 or index is greater 763: * than or equal to the label length. 764: * 765: * @see #getDisplayedMnemonicIndex() 766: * @since 1.4 767: */ 768: public void setDisplayedMnemonicIndex(int newIndex) 769: throws IllegalArgumentException 770: { 771: int maxValid = -1; 772: if (text != null) 773: maxValid = text.length() - 1; 774: if (newIndex < -1 || newIndex > maxValid) 775: throw new IllegalArgumentException(); 776: 777: if (newIndex != displayedMnemonicIndex) 778: { 779: int oldIndex = displayedMnemonicIndex; 780: displayedMnemonicIndex = newIndex; 781: firePropertyChange("displayedMnemonicIndex", oldIndex, newIndex); 782: } 783: } 784: 785: /** 786: * Returns the index of the character in the label's text that will be 787: * underlined (to indicate that it is the mnemonic character), or -1 if no 788: * character is to be underlined. 789: * 790: * @return The index of the character that will be underlined. 791: * 792: * @see #setDisplayedMnemonicIndex(int) 793: * @since 1.4 794: */ 795: public int getDisplayedMnemonicIndex() 796: { 797: return displayedMnemonicIndex; 798: } 799: 800: /** 801: * Checks the specified key to ensure that it is valid as a horizontal 802: * alignment, throwing an {@link IllegalArgumentException} if the key is 803: * invalid. Valid keys are {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 804: * {@link #LEADING} and {@link #TRAILING}. 805: * 806: * @param key The key to check. 807: * @param message The message of the exception to be thrown if the key is 808: * invalid. 809: * 810: * @return The key if it is valid. 811: * 812: * @throws IllegalArgumentException If the key is invalid. 813: */ 814: protected int checkHorizontalKey(int key, String message) 815: { 816: if (key != LEFT && key != CENTER && key != RIGHT && key != LEADING 817: && key != TRAILING) 818: throw new IllegalArgumentException(message); 819: else 820: return key; 821: } 822: 823: /** 824: * Checks the specified key to ensure that it is valid as a vertical 825: * alignment, throwing an {@link IllegalArgumentException} if the key is 826: * invalid. Valid keys are {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}. 827: * 828: * @param key The key to check. 829: * @param message The message of the exception to be thrown if the key is 830: * invalid. 831: * 832: * @return The key if it is valid. 833: * 834: * @throws IllegalArgumentException If the key is invalid. 835: */ 836: protected int checkVerticalKey(int key, String message) 837: { 838: if (key != TOP && key != BOTTOM && key != CENTER) 839: throw new IllegalArgumentException(message); 840: else 841: return key; 842: } 843: 844: /** 845: * Returns the gap between the icon and the text. 846: * 847: * @return The gap between the icon and the text. 848: * 849: * @see #setIconTextGap(int) 850: */ 851: public int getIconTextGap() 852: { 853: return iconTextGap; 854: } 855: 856: /** 857: * Sets the gap between the icon and the text, in the case that both are 858: * visible (this is a bound property with the name 'iconTextGap'). 859: * 860: * @param newGap The gap (in pixels). 861: * 862: * @see #getIconTextGap() 863: */ 864: public void setIconTextGap(int newGap) 865: { 866: if (iconTextGap != newGap) 867: { 868: firePropertyChange("iconTextGap", iconTextGap, newGap); 869: iconTextGap = newGap; 870: } 871: } 872: 873: /** 874: * Returns the vertical alignment of the label (one of 875: * {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}). The default value 876: * depends on the installed look and feel, but is usually {@link #CENTER}. 877: * 878: * @return The vertical alignment. 879: * 880: * @see #setVerticalAlignment(int) 881: */ 882: public int getVerticalAlignment() 883: { 884: return verticalAlignment; 885: } 886: 887: /** 888: * Sets the vertical alignment for the label (this is a bound property with 889: * the name 'verticalAlignment'). The vertical alignment determines where 890: * the label (icon and text) will be placed vertically within the component 891: * bounds. Valid alignment codes are {@link #TOP}, {@link #CENTER} and 892: * {@link #BOTTOM}. 893: * 894: * @param alignment The vertical alignment of the label. 895: * 896: * @throws IllegalArgumentException if <code>alignment</code> is not one of 897: * the specified values. 898: * 899: * @see #getVerticalAlignment() 900: */ 901: public void setVerticalAlignment(int alignment) 902: { 903: if (alignment == verticalAlignment) 904: return; 905: 906: int oldAlignment = verticalAlignment; 907: verticalAlignment = checkVerticalKey(alignment, "verticalAlignment"); 908: firePropertyChange("verticalAlignment", oldAlignment, verticalAlignment); 909: } 910: 911: /** 912: * Returns the horizontal alignment of the label (one of {@link #LEFT}, 913: * {@link #CENTER}, {@link #RIGHT}, {@link #LEADING} and {@link #TRAILING}). 914: * The default value depends on the installed look and feel, but is usually 915: * {@link #LEFT}. 916: * 917: * @return The horizontal alignment. 918: * 919: * @see #setHorizontalAlignment(int) 920: */ 921: public int getHorizontalAlignment() 922: { 923: return horizontalAlignment; 924: } 925: 926: /** 927: * Sets the horizontal alignment for the label (this is a bound property with 928: * the name 'horizontalAlignment'). The horizontal alignment determines where 929: * the label (icon and text) will be placed horizontally within the 930: * component bounds. Valid alignment codes are {@link #LEFT}, 931: * {@link #CENTER}, {@link #RIGHT}, {@link #LEADING} and {@link #TRAILING}. 932: * 933: * @param alignment The horizontal alignment of the label. 934: * 935: * @throws IllegalArgumentException if <code>alignment</code> is not one of 936: * the specified values. 937: * 938: * @see #getHorizontalAlignment() 939: */ 940: public void setHorizontalAlignment(int alignment) 941: { 942: if (horizontalAlignment == alignment) 943: return; 944: 945: int oldAlignment = horizontalAlignment; 946: horizontalAlignment = checkHorizontalKey(alignment, "horizontalAlignment"); 947: firePropertyChange("horizontalAlignment", oldAlignment, 948: horizontalAlignment); 949: } 950: 951: /** 952: * Returns the vertical position of the label's text relative to the icon. 953: * This will be one of {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}. 954: * 955: * @return The vertical position of the label's text relative to the icon. 956: * 957: * @see #setVerticalTextPosition(int) 958: */ 959: public int getVerticalTextPosition() 960: { 961: return verticalTextPosition; 962: } 963: 964: /** 965: * Sets the vertical position of the label's text relative to the icon (this 966: * is a bound property with the name 'verticalTextPosition'). Valid 967: * positions are {@link #TOP}, {@link #CENTER} and {@link #BOTTOM}. 968: * 969: * @param textPosition The vertical text position. 970: * 971: * @throws IllegalArgumentException if <code>textPosition</code> is not one 972: * of the specified values. 973: */ 974: public void setVerticalTextPosition(int textPosition) 975: { 976: if (textPosition != verticalTextPosition) 977: { 978: int oldPos = verticalTextPosition; 979: verticalTextPosition = checkVerticalKey(textPosition, 980: "verticalTextPosition"); 981: firePropertyChange("verticalTextPosition", oldPos, 982: verticalTextPosition); 983: } 984: } 985: 986: /** 987: * Returns the horizontal position of the label's text relative to the icon. 988: * This will be one of {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 989: * {@link #LEADING} and {@link #TRAILING}. 990: * 991: * @return The horizontal position of the label's text relative to the icon. 992: * 993: * @see #setHorizontalTextPosition(int) 994: */ 995: public int getHorizontalTextPosition() 996: { 997: return horizontalTextPosition; 998: } 999: 1000: /** 1001: * Sets the horizontal position of the label's text relative to the icon (this 1002: * is a bound property with the name 'horizontalTextPosition'). Valid 1003: * positions are {@link #LEFT}, {@link #CENTER}, {@link #RIGHT}, 1004: * {@link #LEADING} and {@link #TRAILING}. 1005: * 1006: * @param textPosition The horizontal text position. 1007: * 1008: * @throws IllegalArgumentException if <code>textPosition</code> is not one 1009: * of the specified values. 1010: */ 1011: public void setHorizontalTextPosition(int textPosition) 1012: { 1013: if (textPosition != horizontalTextPosition) 1014: { 1015: int oldPos = horizontalTextPosition; 1016: horizontalTextPosition = checkHorizontalKey(textPosition, 1017: "horizontalTextPosition"); 1018: firePropertyChange("horizontalTextPosition", oldPos, 1019: horizontalTextPosition); 1020: } 1021: } 1022: 1023: /** 1024: * Returns false if the current icon image (current icon will depend on 1025: * whether the label is enabled) is not equal to the passed in image. 1026: * 1027: * @param img The image to check. 1028: * @param infoflags The bitwise inclusive OR of ABORT, ALLBITS, ERROR, 1029: * FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, and WIDTH 1030: * @param x The x position 1031: * @param y The y position 1032: * @param w The width 1033: * @param h The height 1034: * 1035: * @return Whether the current icon image is equal to the image given. 1036: */ 1037: public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, 1038: int h) 1039: { 1040: Icon currIcon = isEnabled() ? icon : disabledIcon; 1041: 1042: // XXX: Is this the correct way to check for image equality? 1043: if (currIcon != null && currIcon instanceof ImageIcon) 1044: return (((ImageIcon) currIcon).getImage() == img); 1045: 1046: return false; 1047: } 1048: 1049: /** 1050: * Returns the component that this <code>JLabel</code> is providing the label 1051: * for. This component will typically receive the focus when the label's 1052: * mnemonic key is activated via the keyboard. 1053: * 1054: * @return The component (possibly <code>null</code>). 1055: */ 1056: public Component getLabelFor() 1057: { 1058: return labelFor; 1059: } 1060: 1061: /** 1062: * Sets the component that this <code>JLabel</code> is providing the label 1063: * for (this is a bound property with the name 'labelFor'). This component 1064: * will typically receive the focus when the label's mnemonic key is 1065: * activated via the keyboard. 1066: * 1067: * @param c the component (<code>null</code> permitted). 1068: * 1069: * @see #getLabelFor() 1070: */ 1071: public void setLabelFor(Component c) 1072: { 1073: if (c != labelFor) 1074: { 1075: Component oldLabelFor = labelFor; 1076: labelFor = c; 1077: firePropertyChange("labelFor", oldLabelFor, labelFor); 1078: 1079: // We put the label into the client properties for the labeled 1080: // component so that it can be read by the AccessibleJComponent. 1081: // The other option would be to reserve a default visible field 1082: // in JComponent, but since this is relatively seldomly used, it 1083: // would be unnecessary waste of memory to do so. 1084: if (oldLabelFor instanceof JComponent) 1085: { 1086: ((JComponent) oldLabelFor).putClientProperty(LABEL_PROPERTY, null); 1087: } 1088: 1089: if (labelFor instanceof JComponent) 1090: { 1091: ((JComponent) labelFor).putClientProperty(LABEL_PROPERTY, this); 1092: } 1093: 1094: } 1095: } 1096: 1097: /** 1098: * Sets the font for the label (this a bound property with the name 'font'). 1099: * 1100: * @param f The font (<code>null</code> permitted). 1101: */ 1102: public void setFont(Font f) 1103: { 1104: super.setFont(f); 1105: repaint(); 1106: } 1107: 1108: /** 1109: * Returns the object that provides accessibility features for this 1110: * <code>JLabel</code> component. 1111: * 1112: * @return The accessible context (an instance of {@link AccessibleJLabel}). 1113: */ 1114: public AccessibleContext getAccessibleContext() 1115: { 1116: if (accessibleContext == null) 1117: accessibleContext = new AccessibleJLabel(); 1118: return accessibleContext; 1119: } 1120: }
GNU Classpath (0.95) |