1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing.text;
  26 
  27 import java.awt.Color;
  28 import java.awt.Component;
  29 import java.awt.Toolkit;
  30 import javax.swing.Icon;
  31 
  32 /**
  33  * <p>
  34  * A collection of <em>well known</em> or common attribute keys
  35  * and methods to apply to an AttributeSet or MutableAttributeSet
  36  * to get/set the properties in a typesafe manner.
  37  * <p>
  38  * The paragraph attributes form the definition of a paragraph to be rendered.
  39  * All sizes are specified in points (such as found in postscript), a
  40  * device independent measure.
  41  * </p>
  42  * <p style="text-align:center"><img src="doc-files/paragraph.gif"
  43  * alt="Diagram shows SpaceAbove, FirstLineIndent, LeftIndent, RightIndent,
  44  *      and SpaceBelow a paragraph."></p>
  45  *
  46  * @author  Timothy Prinzing
  47  */
  48 public class StyleConstants {
  49 
  50     /**
  51      * Name of elements used to represent components.
  52      */
  53     public static final String ComponentElementName = "component";
  54 
  55     /**
  56      * Name of elements used to represent icons.
  57      */
  58     public static final String IconElementName = "icon";
  59 
  60     /**
  61      * Attribute name used to name the collection of
  62      * attributes.
  63      */
  64     public static final Object NameAttribute = new StyleConstants("name");
  65 
  66     /**
  67      * Attribute name used to identify the resolving parent
  68      * set of attributes, if one is defined.
  69      */
  70     public static final Object ResolveAttribute = new StyleConstants("resolver");
  71 
  72     /**
  73      * Attribute used to identify the model for embedded
  74      * objects that have a model view separation.
  75      */
  76     public static final Object ModelAttribute = new StyleConstants("model");
  77 
  78     /**
  79      * Returns the string representation.
  80      *
  81      * @return the string
  82      */
  83     public String toString() {
  84         return representation;
  85     }
  86 
  87     // ---- character constants -----------------------------------
  88 
  89     /**
  90      * Bidirectional level of a character as assigned by the Unicode bidi
  91      * algorithm.
  92      */
  93     public static final Object BidiLevel = new CharacterConstants("bidiLevel");
  94 
  95     /**
  96      * Name of the font family.
  97      */
  98     public static final Object FontFamily = new FontConstants("family");
  99 
 100     /**
 101      * Name of the font family.
 102      *
 103      * @since 1.5
 104      */
 105     public static final Object Family = FontFamily;
 106 
 107     /**
 108      * Name of the font size.
 109      */
 110     public static final Object FontSize = new FontConstants("size");
 111 
 112     /**
 113      * Name of the font size.
 114      *
 115      * @since 1.5
 116      */
 117     public static final Object Size = FontSize;
 118 
 119     /**
 120      * Name of the bold attribute.
 121      */
 122     public static final Object Bold = new FontConstants("bold");
 123 
 124     /**
 125      * Name of the italic attribute.
 126      */
 127     public static final Object Italic = new FontConstants("italic");
 128 
 129     /**
 130      * Name of the underline attribute.
 131      */
 132     public static final Object Underline = new CharacterConstants("underline");
 133 
 134     /**
 135      * Name of the Strikethrough attribute.
 136      */
 137     public static final Object StrikeThrough = new CharacterConstants("strikethrough");
 138 
 139     /**
 140      * Name of the Superscript attribute.
 141      */
 142     public static final Object Superscript = new CharacterConstants("superscript");
 143 
 144     /**
 145      * Name of the Subscript attribute.
 146      */
 147     public static final Object Subscript = new CharacterConstants("subscript");
 148 
 149     /**
 150      * Name of the foreground color attribute.
 151      */
 152     public static final Object Foreground = new ColorConstants("foreground");
 153 
 154     /**
 155      * Name of the background color attribute.
 156      */
 157     public static final Object Background = new ColorConstants("background");
 158 
 159     /**
 160      * Name of the component attribute.
 161      */
 162     public static final Object ComponentAttribute = new CharacterConstants("component");
 163 
 164     /**
 165      * Name of the icon attribute.
 166      */
 167     public static final Object IconAttribute = new CharacterConstants("icon");
 168 
 169     /**
 170      * Name of the input method composed text attribute. The value of
 171      * this attribute is an instance of AttributedString which represents
 172      * the composed text.
 173      */
 174     public static final Object ComposedTextAttribute = new StyleConstants("composed text");
 175 
 176     /**
 177      * The amount of space to indent the first
 178      * line of the paragraph.  This value may be negative
 179      * to offset in the reverse direction.  The type
 180      * is Float and specifies the size of the space
 181      * in points.
 182      */
 183     public static final Object FirstLineIndent = new ParagraphConstants("FirstLineIndent");
 184 
 185     /**
 186      * The amount to indent the left side
 187      * of the paragraph.
 188      * Type is float and specifies the size in points.
 189      */
 190     public static final Object LeftIndent = new ParagraphConstants("LeftIndent");
 191 
 192     /**
 193      * The amount to indent the right side
 194      * of the paragraph.
 195      * Type is float and specifies the size in points.
 196      */
 197     public static final Object RightIndent = new ParagraphConstants("RightIndent");
 198 
 199     /**
 200      * The amount of space between lines
 201      * of the paragraph.
 202      * Type is float and specifies the size as a factor of the line height
 203      */
 204     public static final Object LineSpacing = new ParagraphConstants("LineSpacing");
 205 
 206     /**
 207      * The amount of space above the paragraph.
 208      * Type is float and specifies the size in points.
 209      */
 210     public static final Object SpaceAbove = new ParagraphConstants("SpaceAbove");
 211 
 212     /**
 213      * The amount of space below the paragraph.
 214      * Type is float and specifies the size in points.
 215      */
 216     public static final Object SpaceBelow = new ParagraphConstants("SpaceBelow");
 217 
 218     /**
 219      * Alignment for the paragraph.  The type is
 220      * Integer.  Valid values are:
 221      * <ul>
 222      * <li>ALIGN_LEFT
 223      * <li>ALIGN_RIGHT
 224      * <li>ALIGN_CENTER
 225      * <li>ALIGN_JUSTIFED
 226      * </ul>
 227      *
 228      */
 229     public static final Object Alignment = new ParagraphConstants("Alignment");
 230 
 231     /**
 232      * TabSet for the paragraph, type is a TabSet containing
 233      * TabStops.
 234      */
 235     public static final Object TabSet = new ParagraphConstants("TabSet");
 236 
 237     /**
 238      * Orientation for a paragraph.
 239      */
 240     public static final Object Orientation = new ParagraphConstants("Orientation");
 241     /**
 242      * A possible value for paragraph alignment.  This
 243      * specifies that the text is aligned to the left
 244      * indent and extra whitespace should be placed on
 245      * the right.
 246      */
 247     public static final int ALIGN_LEFT = 0;
 248 
 249     /**
 250      * A possible value for paragraph alignment.  This
 251      * specifies that the text is aligned to the center
 252      * and extra whitespace should be placed equally on
 253      * the left and right.
 254      */
 255     public static final int ALIGN_CENTER = 1;
 256 
 257     /**
 258      * A possible value for paragraph alignment.  This
 259      * specifies that the text is aligned to the right
 260      * indent and extra whitespace should be placed on
 261      * the left.
 262      */
 263     public static final int ALIGN_RIGHT = 2;
 264 
 265     /**
 266      * A possible value for paragraph alignment.  This
 267      * specifies that extra whitespace should be spread
 268      * out through the rows of the paragraph with the
 269      * text lined up with the left and right indent
 270      * except on the last line which should be aligned
 271      * to the left.
 272      */
 273     public static final int ALIGN_JUSTIFIED = 3;
 274 
 275     // --- character attribute accessors ---------------------------
 276 
 277     /**
 278      * Gets the BidiLevel setting.
 279      *
 280      * @param a the attribute set
 281      * @return the value
 282      */
 283     public static int getBidiLevel(AttributeSet a) {
 284         Integer o = (Integer) a.getAttribute(BidiLevel);
 285         if (o != null) {
 286             return o.intValue();
 287         }
 288         return 0;  // Level 0 is base level (non-embedded) left-to-right
 289     }
 290 
 291     /**
 292      * Sets the BidiLevel.
 293      *
 294      * @param a the attribute set
 295      * @param o the bidi level value
 296      */
 297     public static void setBidiLevel(MutableAttributeSet a, int o) {
 298         a.addAttribute(BidiLevel, Integer.valueOf(o));
 299     }
 300 
 301     /**
 302      * Gets the component setting from the attribute list.
 303      *
 304      * @param a the attribute set
 305      * @return the component, null if none
 306      */
 307     public static Component getComponent(AttributeSet a) {
 308         return (Component) a.getAttribute(ComponentAttribute);
 309     }
 310 
 311     /**
 312      * Sets the component attribute.
 313      *
 314      * @param a the attribute set
 315      * @param c the component
 316      */
 317     public static void setComponent(MutableAttributeSet a, Component c) {
 318         a.addAttribute(AbstractDocument.ElementNameAttribute, ComponentElementName);
 319         a.addAttribute(ComponentAttribute, c);
 320     }
 321 
 322     /**
 323      * Gets the icon setting from the attribute list.
 324      *
 325      * @param a the attribute set
 326      * @return the icon, null if none
 327      */
 328     public static Icon getIcon(AttributeSet a) {
 329         return (Icon) a.getAttribute(IconAttribute);
 330     }
 331 
 332     /**
 333      * Sets the icon attribute.
 334      *
 335      * @param a the attribute set
 336      * @param c the icon
 337      */
 338     public static void setIcon(MutableAttributeSet a, Icon c) {
 339         a.addAttribute(AbstractDocument.ElementNameAttribute, IconElementName);
 340         a.addAttribute(IconAttribute, c);
 341     }
 342 
 343     /**
 344      * Gets the font family setting from the attribute list.
 345      *
 346      * @param a the attribute set
 347      * @return the font family, "Monospaced" as the default
 348      */
 349     public static String getFontFamily(AttributeSet a) {
 350         String family = (String) a.getAttribute(FontFamily);
 351         if (family == null) {
 352             family = "Monospaced";
 353         }
 354         return family;
 355     }
 356 
 357     /**
 358      * Sets the font attribute.
 359      *
 360      * @param a the attribute set
 361      * @param fam the font
 362      */
 363     public static void setFontFamily(MutableAttributeSet a, String fam) {
 364         a.addAttribute(FontFamily, fam);
 365     }
 366 
 367     /**
 368      * Gets the font size setting from the attribute list.
 369      *
 370      * @param a the attribute set
 371      * @return the font size, 12 as the default
 372      */
 373     public static int getFontSize(AttributeSet a) {
 374         Integer size = (Integer) a.getAttribute(FontSize);
 375         if (size != null) {
 376             return size.intValue();
 377         }
 378         return 12;
 379     }
 380 
 381     /**
 382      * Sets the font size attribute.
 383      *
 384      * @param a the attribute set
 385      * @param s the font size
 386      */
 387     public static void setFontSize(MutableAttributeSet a, int s) {
 388         a.addAttribute(FontSize, Integer.valueOf(s));
 389     }
 390 
 391     /**
 392      * Checks whether the bold attribute is set.
 393      *
 394      * @param a the attribute set
 395      * @return true if set else false
 396      */
 397     public static boolean isBold(AttributeSet a) {
 398         Boolean bold = (Boolean) a.getAttribute(Bold);
 399         if (bold != null) {
 400             return bold.booleanValue();
 401         }
 402         return false;
 403     }
 404 
 405     /**
 406      * Sets the bold attribute.
 407      *
 408      * @param a the attribute set
 409      * @param b specifies true/false for setting the attribute
 410      */
 411     public static void setBold(MutableAttributeSet a, boolean b) {
 412         a.addAttribute(Bold, Boolean.valueOf(b));
 413     }
 414 
 415     /**
 416      * Checks whether the italic attribute is set.
 417      *
 418      * @param a the attribute set
 419      * @return true if set else false
 420      */
 421     public static boolean isItalic(AttributeSet a) {
 422         Boolean italic = (Boolean) a.getAttribute(Italic);
 423         if (italic != null) {
 424             return italic.booleanValue();
 425         }
 426         return false;
 427     }
 428 
 429     /**
 430      * Sets the italic attribute.
 431      *
 432      * @param a the attribute set
 433      * @param b specifies true/false for setting the attribute
 434      */
 435     public static void setItalic(MutableAttributeSet a, boolean b) {
 436         a.addAttribute(Italic, Boolean.valueOf(b));
 437     }
 438 
 439     /**
 440      * Checks whether the underline attribute is set.
 441      *
 442      * @param a the attribute set
 443      * @return true if set else false
 444      */
 445     public static boolean isUnderline(AttributeSet a) {
 446         Boolean underline = (Boolean) a.getAttribute(Underline);
 447         if (underline != null) {
 448             return underline.booleanValue();
 449         }
 450         return false;
 451     }
 452 
 453     /**
 454      * Checks whether the strikethrough attribute is set.
 455      *
 456      * @param a the attribute set
 457      * @return true if set else false
 458      */
 459     public static boolean isStrikeThrough(AttributeSet a) {
 460         Boolean strike = (Boolean) a.getAttribute(StrikeThrough);
 461         if (strike != null) {
 462             return strike.booleanValue();
 463         }
 464         return false;
 465     }
 466 
 467 
 468     /**
 469      * Checks whether the superscript attribute is set.
 470      *
 471      * @param a the attribute set
 472      * @return true if set else false
 473      */
 474     public static boolean isSuperscript(AttributeSet a) {
 475         Boolean superscript = (Boolean) a.getAttribute(Superscript);
 476         if (superscript != null) {
 477             return superscript.booleanValue();
 478         }
 479         return false;
 480     }
 481 
 482 
 483     /**
 484      * Checks whether the subscript attribute is set.
 485      *
 486      * @param a the attribute set
 487      * @return true if set else false
 488      */
 489     public static boolean isSubscript(AttributeSet a) {
 490         Boolean subscript = (Boolean) a.getAttribute(Subscript);
 491         if (subscript != null) {
 492             return subscript.booleanValue();
 493         }
 494         return false;
 495     }
 496 
 497 
 498     /**
 499      * Sets the underline attribute.
 500      *
 501      * @param a the attribute set
 502      * @param b specifies true/false for setting the attribute
 503      */
 504     public static void setUnderline(MutableAttributeSet a, boolean b) {
 505         a.addAttribute(Underline, Boolean.valueOf(b));
 506     }
 507 
 508     /**
 509      * Sets the strikethrough attribute.
 510      *
 511      * @param a the attribute set
 512      * @param b specifies true/false for setting the attribute
 513      */
 514     public static void setStrikeThrough(MutableAttributeSet a, boolean b) {
 515         a.addAttribute(StrikeThrough, Boolean.valueOf(b));
 516     }
 517 
 518     /**
 519      * Sets the superscript attribute.
 520      *
 521      * @param a the attribute set
 522      * @param b specifies true/false for setting the attribute
 523      */
 524     public static void setSuperscript(MutableAttributeSet a, boolean b) {
 525         a.addAttribute(Superscript, Boolean.valueOf(b));
 526     }
 527 
 528     /**
 529      * Sets the subscript attribute.
 530      *
 531      * @param a the attribute set
 532      * @param b specifies true/false for setting the attribute
 533      */
 534     public static void setSubscript(MutableAttributeSet a, boolean b) {
 535         a.addAttribute(Subscript, Boolean.valueOf(b));
 536     }
 537 
 538 
 539     /**
 540      * Gets the foreground color setting from the attribute list.
 541      *
 542      * @param a the attribute set
 543      * @return the color, Color.black as the default
 544      */
 545     public static Color getForeground(AttributeSet a) {
 546         Color fg = (Color) a.getAttribute(Foreground);
 547         if (fg == null) {
 548             fg = Color.black;
 549         }
 550         return fg;
 551     }
 552 
 553     /**
 554      * Sets the foreground color.
 555      *
 556      * @param a the attribute set
 557      * @param fg the color
 558      */
 559     public static void setForeground(MutableAttributeSet a, Color fg) {
 560         a.addAttribute(Foreground, fg);
 561     }
 562 
 563     /**
 564      * Gets the background color setting from the attribute list.
 565      *
 566      * @param a the attribute set
 567      * @return the color, Color.black as the default
 568      */
 569     public static Color getBackground(AttributeSet a) {
 570         Color fg = (Color) a.getAttribute(Background);
 571         if (fg == null) {
 572             fg = Color.black;
 573         }
 574         return fg;
 575     }
 576 
 577     /**
 578      * Sets the background color.
 579      *
 580      * @param a the attribute set
 581      * @param fg the color
 582      */
 583     public static void setBackground(MutableAttributeSet a, Color fg) {
 584         a.addAttribute(Background, fg);
 585     }
 586 
 587 
 588     // --- paragraph attribute accessors ----------------------------
 589 
 590     /**
 591      * Gets the first line indent setting.
 592      *
 593      * @param a the attribute set
 594      * @return the value, 0 if not set
 595      */
 596     public static float getFirstLineIndent(AttributeSet a) {
 597         Float indent = (Float) a.getAttribute(FirstLineIndent);
 598         if (indent != null) {
 599             return indent.floatValue();
 600         }
 601         return 0;
 602     }
 603 
 604     /**
 605      * Sets the first line indent.
 606      *
 607      * @param a the attribute set
 608      * @param i the value
 609      */
 610     public static void setFirstLineIndent(MutableAttributeSet a, float i) {
 611         a.addAttribute(FirstLineIndent, new Float(i));
 612     }
 613 
 614     /**
 615      * Gets the right indent setting.
 616      *
 617      * @param a the attribute set
 618      * @return the value, 0 if not set
 619      */
 620     public static float getRightIndent(AttributeSet a) {
 621         Float indent = (Float) a.getAttribute(RightIndent);
 622         if (indent != null) {
 623             return indent.floatValue();
 624         }
 625         return 0;
 626     }
 627 
 628     /**
 629      * Sets right indent.
 630      *
 631      * @param a the attribute set
 632      * @param i the value
 633      */
 634     public static void setRightIndent(MutableAttributeSet a, float i) {
 635         a.addAttribute(RightIndent, new Float(i));
 636     }
 637 
 638     /**
 639      * Gets the left indent setting.
 640      *
 641      * @param a the attribute set
 642      * @return the value, 0 if not set
 643      */
 644     public static float getLeftIndent(AttributeSet a) {
 645         Float indent = (Float) a.getAttribute(LeftIndent);
 646         if (indent != null) {
 647             return indent.floatValue();
 648         }
 649         return 0;
 650     }
 651 
 652     /**
 653      * Sets left indent.
 654      *
 655      * @param a the attribute set
 656      * @param i the value
 657      */
 658     public static void setLeftIndent(MutableAttributeSet a, float i) {
 659         a.addAttribute(LeftIndent, new Float(i));
 660     }
 661 
 662     /**
 663      * Gets the line spacing setting.
 664      *
 665      * @param a the attribute set
 666      * @return the value, 0 if not set
 667      */
 668     public static float getLineSpacing(AttributeSet a) {
 669         Float space = (Float) a.getAttribute(LineSpacing);
 670         if (space != null) {
 671             return space.floatValue();
 672         }
 673         return 0;
 674     }
 675 
 676     /**
 677      * Sets line spacing.
 678      *
 679      * @param a the attribute set
 680      * @param i the value
 681      */
 682     public static void setLineSpacing(MutableAttributeSet a, float i) {
 683         a.addAttribute(LineSpacing, new Float(i));
 684     }
 685 
 686     /**
 687      * Gets the space above setting.
 688      *
 689      * @param a the attribute set
 690      * @return the value, 0 if not set
 691      */
 692     public static float getSpaceAbove(AttributeSet a) {
 693         Float space = (Float) a.getAttribute(SpaceAbove);
 694         if (space != null) {
 695             return space.floatValue();
 696         }
 697         return 0;
 698     }
 699 
 700     /**
 701      * Sets space above.
 702      *
 703      * @param a the attribute set
 704      * @param i the value
 705      */
 706     public static void setSpaceAbove(MutableAttributeSet a, float i) {
 707         a.addAttribute(SpaceAbove, new Float(i));
 708     }
 709 
 710     /**
 711      * Gets the space below setting.
 712      *
 713      * @param a the attribute set
 714      * @return the value, 0 if not set
 715      */
 716     public static float getSpaceBelow(AttributeSet a) {
 717         Float space = (Float) a.getAttribute(SpaceBelow);
 718         if (space != null) {
 719             return space.floatValue();
 720         }
 721         return 0;
 722     }
 723 
 724     /**
 725      * Sets space below.
 726      *
 727      * @param a the attribute set
 728      * @param i the value
 729      */
 730     public static void setSpaceBelow(MutableAttributeSet a, float i) {
 731         a.addAttribute(SpaceBelow, new Float(i));
 732     }
 733 
 734     /**
 735      * Gets the alignment setting.
 736      *
 737      * @param a the attribute set
 738      * @return the value <code>StyleConstants.ALIGN_LEFT</code> if not set
 739      */
 740     public static int getAlignment(AttributeSet a) {
 741         Integer align = (Integer) a.getAttribute(Alignment);
 742         if (align != null) {
 743             return align.intValue();
 744         }
 745         return ALIGN_LEFT;
 746     }
 747 
 748     /**
 749      * Sets alignment.
 750      *
 751      * @param a the attribute set
 752      * @param align the alignment value
 753      */
 754     public static void setAlignment(MutableAttributeSet a, int align) {
 755         a.addAttribute(Alignment, Integer.valueOf(align));
 756     }
 757 
 758     /**
 759      * Gets the TabSet.
 760      *
 761      * @param a the attribute set
 762      * @return the <code>TabSet</code>
 763      */
 764     public static TabSet getTabSet(AttributeSet a) {
 765         TabSet tabs = (TabSet)a.getAttribute(TabSet);
 766         // PENDING: should this return a default?
 767         return tabs;
 768     }
 769 
 770     /**
 771      * Sets the TabSet.
 772      *
 773      * @param a the attribute set.
 774      * @param tabs the TabSet
 775      */
 776     public static void setTabSet(MutableAttributeSet a, TabSet tabs) {
 777         a.addAttribute(TabSet, tabs);
 778     }
 779 
 780     // --- privates ---------------------------------------------
 781 
 782     static Object[] keys = {
 783         NameAttribute, ResolveAttribute, BidiLevel,
 784         FontFamily, FontSize, Bold, Italic, Underline,
 785         StrikeThrough, Superscript, Subscript, Foreground,
 786         Background, ComponentAttribute, IconAttribute,
 787         FirstLineIndent, LeftIndent, RightIndent, LineSpacing,
 788         SpaceAbove, SpaceBelow, Alignment, TabSet, Orientation,
 789         ModelAttribute, ComposedTextAttribute
 790     };
 791 
 792     StyleConstants(String representation) {
 793         this.representation = representation;
 794     }
 795 
 796     private String representation;
 797 
 798     /**
 799      * This is a typesafe enumeration of the <em>well-known</em>
 800      * attributes that contribute to a paragraph style.  These are
 801      * aliased by the outer class for general presentation.
 802      */
 803     public static class ParagraphConstants extends StyleConstants
 804         implements AttributeSet.ParagraphAttribute {
 805 
 806         private ParagraphConstants(String representation) {
 807             super(representation);
 808         }
 809     }
 810 
 811     /**
 812      * This is a typesafe enumeration of the <em>well-known</em>
 813      * attributes that contribute to a character style.  These are
 814      * aliased by the outer class for general presentation.
 815      */
 816     public static class CharacterConstants extends StyleConstants
 817         implements AttributeSet.CharacterAttribute {
 818 
 819         private CharacterConstants(String representation) {
 820             super(representation);
 821         }
 822     }
 823 
 824     /**
 825      * This is a typesafe enumeration of the <em>well-known</em>
 826      * attributes that contribute to a color.  These are aliased
 827      * by the outer class for general presentation.
 828      */
 829     public static class ColorConstants extends StyleConstants
 830         implements AttributeSet.ColorAttribute,  AttributeSet.CharacterAttribute {
 831 
 832         private ColorConstants(String representation) {
 833             super(representation);
 834         }
 835     }
 836 
 837     /**
 838      * This is a typesafe enumeration of the <em>well-known</em>
 839      * attributes that contribute to a font.  These are aliased
 840      * by the outer class for general presentation.
 841      */
 842     public static class FontConstants extends StyleConstants
 843         implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute {
 844 
 845         private FontConstants(String representation) {
 846             super(representation);
 847         }
 848     }
 849 
 850 
 851 }