Java Code Examples for java.text.AttributedCharacterIterator#getAttribute()

The following examples show how to use java.text.AttributedCharacterIterator#getAttribute() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LineLayout.java    From ttt with BSD 2-Clause "Simplified" License 6 votes vote down vote up
private List<StyleAttributeInterval> getVisibilityIntervals(int from, int to) {
    StyleAttribute visibilityAttr = StyleAttribute.VISIBILITY;
    List<StyleAttributeInterval> visibilities = new java.util.ArrayList<StyleAttributeInterval>();
    int[] intervals = getAttributeIntervals(from, to, visibilityAttr);
    AttributedCharacterIterator aci = iterator;
    int savedIndex = aci.getIndex();
    for (int i = 0, n = intervals.length / 2; i < n; ++i) {
        int s = start + intervals[i*2 + 0];
        int e = start + intervals[i*2 + 1];
        aci.setIndex(s);
        Object v = aci.getAttribute(visibilityAttr);
        if (v != null)
            visibilities.add(new StyleAttributeInterval(visibilityAttr, v, s, e));
    }
    aci.setIndex(savedIndex);
    if (visibilities.isEmpty() && (visibility != null) && !visibility.equals(defaults.getVisibility()))
        visibilities.add(new StyleAttributeInterval(visibilityAttr, visibility, start + from, start + to));
    return visibilities;
}
 
Example 2
Source File: Support_Format.java    From j2objc with Apache License 2.0 6 votes vote down vote up
/**
 * finds attributes with regards to char index in this
 * AttributedCharacterIterator, and puts them in a vector
 *
 * @param iterator
 * @return a vector, each entry in this vector are of type FieldContainer,
 *       which stores start and end indexes and an attribute this range has
 */
protected static Vector<FieldContainer> findFields(AttributedCharacterIterator iterator) {
  Vector<FieldContainer> result = new Vector<FieldContainer>();
  while (iterator.getIndex() != iterator.getEndIndex()) {
    int start = iterator.getRunStart();
    int end = iterator.getRunLimit();

    Iterator<Attribute> it = iterator.getAttributes().keySet().iterator();
    while (it.hasNext()) {
      AttributedCharacterIterator.Attribute attribute = it.next();
      Object value = iterator.getAttribute(attribute);
      result.add(new FieldContainer(start, end, attribute, value));
      // System.out.println(start + " " + end + ": " + attribute + ",
      // " + value );
      // System.out.println("v.add(new FieldContainer(" + start +"," +
      // end +"," + attribute+ "," + value+ "));");
    }
    iterator.setIndex(end);
  }
  return result;
}
 
Example 3
Source File: TextLine.java    From dragonwell8_jdk with GNU General Public License v2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 4
Source File: TextLine.java    From JDKSourceCode1.8 with MIT License 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 5
Source File: TextLine.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 6
Source File: TextLine.java    From openjdk-jdk9 with GNU General Public License v2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 7
Source File: MaxFontSizeFinder.java    From jasperreports with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Override
public float findMaxFontSize(AttributedCharacterIterator line, float defaultFontSize)
{
	line.setIndex(0);
	Float maxFontSize = ZERO;
	int runLimit = 0;
	
	while(runLimit < line.getEndIndex() && (runLimit = line.getRunLimit(TextAttribute.SIZE)) <= line.getEndIndex())
	{
		Float size = (Float)line.getAttribute(TextAttribute.SIZE);
		if (maxFontSize.compareTo(size) < 0)
		{
			maxFontSize = size;
		}
		line.setIndex(runLimit);
	}
	
	return maxFontSize;
}
 
Example 8
Source File: TextLine.java    From TencentKona-8 with GNU General Public License v2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 9
Source File: TextLine.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 10
Source File: TextLine.java    From jdk-1.7-annotated with Apache License 2.0 6 votes vote down vote up
static Font getFontAtCurrentPos(AttributedCharacterIterator aci) {

        Object value = aci.getAttribute(TextAttribute.FONT);
        if (value != null) {
            return (Font) value;
        }
        if (aci.getAttribute(TextAttribute.FAMILY) != null) {
            return Font.getFont(aci.getAttributes());
        }

        int ch = CodePointIterator.create(aci).next();
        if (ch != CodePointIterator.DONE) {
            FontResolver resolver = FontResolver.getInstance();
            return resolver.getFont(resolver.getFontIndex(ch), aci.getAttributes());
        }
        return null;
    }
 
Example 11
Source File: TextLine.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
/**
 * When this returns, the ACI's current position will be at the start of the
 * first run which does NOT contain a GraphicAttribute.  If no such run exists
 * the ACI's position will be at the end, and this method will return false.
 */
static boolean advanceToFirstFont(AttributedCharacterIterator aci) {

    for (char ch = aci.first(); ch != aci.DONE; ch = aci.setIndex(aci.getRunLimit())) {

        if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) {
            return true;
        }
    }

    return false;
}
 
Example 12
Source File: AttributedStringTest.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
private static final void checkIteratorAttribute(AttributedCharacterIterator iterator, int index, Attribute key, Object expectedValue) throws Exception {
    iterator.setIndex(index);
    Object value = iterator.getAttribute(key);
    if (!((expectedValue == null && value == null) || (expectedValue != null && expectedValue.equals(value)))) {
        throwException(iterator, "iterator returns wrong attribute value - " + value + " instead of " + expectedValue);
    }
    value = iterator.getAttributes().get(key);
    if (!((expectedValue == null && value == null) || (expectedValue != null && expectedValue.equals(value)))) {
        throwException(iterator, "iterator's map returns wrong attribute value - " + value + " instead of " + expectedValue);
    }
}
 
Example 13
Source File: TextLine.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * When this returns, the ACI's current position will be at the start of the
 * first run which does NOT contain a GraphicAttribute.  If no such run exists
 * the ACI's position will be at the end, and this method will return false.
 */
static boolean advanceToFirstFont(AttributedCharacterIterator aci) {

    for (char ch = aci.first();
         ch != CharacterIterator.DONE;
         ch = aci.setIndex(aci.getRunLimit()))
    {

        if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) {
            return true;
        }
    }

    return false;
}
 
Example 14
Source File: TextLine.java    From Java8CN with Apache License 2.0 5 votes vote down vote up
/**
 * When this returns, the ACI's current position will be at the start of the
 * first run which does NOT contain a GraphicAttribute.  If no such run exists
 * the ACI's position will be at the end, and this method will return false.
 */
static boolean advanceToFirstFont(AttributedCharacterIterator aci) {

    for (char ch = aci.first();
         ch != CharacterIterator.DONE;
         ch = aci.setIndex(aci.getRunLimit()))
    {

        if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) {
            return true;
        }
    }

    return false;
}
 
Example 15
Source File: TextLine.java    From Bytecoder with Apache License 2.0 5 votes vote down vote up
/**
 * When this returns, the ACI's current position will be at the start of the
 * first run which does NOT contain a GraphicAttribute.  If no such run exists
 * the ACI's position will be at the end, and this method will return false.
 */
static boolean advanceToFirstFont(AttributedCharacterIterator aci) {

    for (char ch = aci.first();
         ch != CharacterIterator.DONE;
         ch = aci.setIndex(aci.getRunLimit()))
    {

        if (aci.getAttribute(TextAttribute.CHAR_REPLACEMENT) == null) {
            return true;
        }
    }

    return false;
}
 
Example 16
Source File: getRunStartLimitTest.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
public static void main(String[] args) throws Exception {

        String text = "Hello world";
        AttributedString as = new AttributedString(text);

        // add non-Annotation attributes
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_LIGHT,
                        0,
                        3);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_BOLD,
                        3,
                        5);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_EXTRABOLD,
                        5,
                        text.length());

        // add Annotation attributes
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_EXTENDED),
                        0,
                        3);
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_CONDENSED),
                        3,
                        4);

        AttributedCharacterIterator aci = as.getIterator(null, 2, 4);

        aci.first();
        int runStart = aci.getRunStart();
        if (runStart != 2) {
            throw new Exception("1st run start is wrong. ("+runStart+" should be 2.)");
        }

        int runLimit = aci.getRunLimit();
        if (runLimit != 3) {
            throw new Exception("1st run limit is wrong. ("+runLimit+" should be 3.)");
        }

        Object value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_LIGHT) {
            throw new Exception("1st run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_LIGHT+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (value != null) {
            throw new Exception("1st run annotation is wrong. ("
                                +value+" should be null.)");
        }

        aci.setIndex(runLimit);
        runStart = aci.getRunStart();
        if (runStart != 3) {
            throw new Exception("2nd run start is wrong. ("+runStart+" should be 3.)");
        }

        runLimit = aci.getRunLimit();
        if (runLimit != 4) {
            throw new Exception("2nd run limit is wrong. ("+runLimit+" should be 4.)");
        }
        value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_BOLD) {
            throw new Exception("2nd run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_BOLD+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (!(value instanceof Annotation)
            || (((Annotation)value).getValue() !=  TextAttribute.WIDTH_CONDENSED)) {
            throw new Exception("2nd run annotation is wrong. (" + value + " should be "
                                + new Annotation(TextAttribute.WIDTH_CONDENSED)+".)");
        }
    }
 
Example 17
Source File: BidiBase.java    From jdk8u-jdk with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the
 * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
 * version 13,
 * also described in The Unicode Standard, Version 4.0 .<p>
 *
 * This method takes a paragraph of text and computes the
 * left-right-directionality of each character. The text should not
 * contain any Unicode block separators.<p>
 *
 * The RUN_DIRECTION attribute in the text, if present, determines the base
 * direction (left-to-right or right-to-left). If not present, the base
 * direction is computed using the Unicode Bidirectional Algorithm,
 * defaulting to left-to-right if there are no strong directional characters
 * in the text. This attribute, if present, must be applied to all the text
 * in the paragraph.<p>
 *
 * The BIDI_EMBEDDING attribute in the text, if present, represents
 * embedding level information. Negative values from -1 to -62 indicate
 * overrides at the absolute value of the level. Positive values from 1 to
 * 62 indicate embeddings. Where values are zero or not defined, the base
 * embedding level as determined by the base direction is assumed.<p>
 *
 * The NUMERIC_SHAPING attribute in the text, if present, converts European
 * digits to other decimal digits before running the bidi algorithm. This
 * attribute, if present, must be applied to all the text in the paragraph.
 *
 * If the entire text is all of the same directionality, then
 * the method may not perform all the steps described by the algorithm,
 * i.e., some levels may not be the same as if all steps were performed.
 * This is not relevant for unidirectional text.<br>
 * For example, in pure LTR text with numbers the numbers would get
 * a resolved level of 2 higher than the surrounding text according to
 * the algorithm. This implementation may set all resolved levels to
 * the same value in such a case.<p>
 *
 * @param paragraph a paragraph of text with optional character and
 *        paragraph attribute information
 * @stable ICU 3.8
 */
public void setPara(AttributedCharacterIterator paragraph)
{
    byte paraLvl;
    char ch = paragraph.first();
    Boolean runDirection =
        (Boolean) paragraph.getAttribute(TextAttributeConstants.RUN_DIRECTION);
    Object shaper = paragraph.getAttribute(TextAttributeConstants.NUMERIC_SHAPING);
    if (runDirection == null) {
        paraLvl = INTERNAL_LEVEL_DEFAULT_LTR;
    } else {
        paraLvl = (runDirection.equals(TextAttributeConstants.RUN_DIRECTION_LTR)) ?
                    (byte)Bidi.DIRECTION_LEFT_TO_RIGHT : (byte)Bidi.DIRECTION_RIGHT_TO_LEFT;
    }

    byte[] lvls = null;
    int len = paragraph.getEndIndex() - paragraph.getBeginIndex();
    byte[] embeddingLevels = new byte[len];
    char[] txt = new char[len];
    int i = 0;
    while (ch != AttributedCharacterIterator.DONE) {
        txt[i] = ch;
        Integer embedding =
            (Integer) paragraph.getAttribute(TextAttributeConstants.BIDI_EMBEDDING);
        if (embedding != null) {
            byte level = embedding.byteValue();
            if (level == 0) {
                /* no-op */
            } else if (level < 0) {
                lvls = embeddingLevels;
                embeddingLevels[i] = (byte)((0 - level) | INTERNAL_LEVEL_OVERRIDE);
            } else {
                lvls = embeddingLevels;
                embeddingLevels[i] = level;
            }
        }
        ch = paragraph.next();
        ++i;
    }

    if (shaper != null) {
        NumericShapings.shape(shaper, txt, 0, len);
    }
    setPara(txt, paraLvl, lvls);
}
 
Example 18
Source File: getRunStartLimitTest.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
public static void main(String[] args) throws Exception {

        String text = "Hello world";
        AttributedString as = new AttributedString(text);

        // add non-Annotation attributes
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_LIGHT,
                        0,
                        3);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_BOLD,
                        3,
                        5);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_EXTRABOLD,
                        5,
                        text.length());

        // add Annotation attributes
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_EXTENDED),
                        0,
                        3);
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_CONDENSED),
                        3,
                        4);

        AttributedCharacterIterator aci = as.getIterator(null, 2, 4);

        aci.first();
        int runStart = aci.getRunStart();
        if (runStart != 2) {
            throw new Exception("1st run start is wrong. ("+runStart+" should be 2.)");
        }

        int runLimit = aci.getRunLimit();
        if (runLimit != 3) {
            throw new Exception("1st run limit is wrong. ("+runLimit+" should be 3.)");
        }

        Object value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_LIGHT) {
            throw new Exception("1st run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_LIGHT+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (value != null) {
            throw new Exception("1st run annotation is wrong. ("
                                +value+" should be null.)");
        }

        aci.setIndex(runLimit);
        runStart = aci.getRunStart();
        if (runStart != 3) {
            throw new Exception("2nd run start is wrong. ("+runStart+" should be 3.)");
        }

        runLimit = aci.getRunLimit();
        if (runLimit != 4) {
            throw new Exception("2nd run limit is wrong. ("+runLimit+" should be 4.)");
        }
        value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_BOLD) {
            throw new Exception("2nd run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_BOLD+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (!(value instanceof Annotation)
            || (((Annotation)value).getValue() !=  TextAttribute.WIDTH_CONDENSED)) {
            throw new Exception("2nd run annotation is wrong. (" + value + " should be "
                                + new Annotation(TextAttribute.WIDTH_CONDENSED)+".)");
        }
    }
 
Example 19
Source File: BidiBase.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Perform the Unicode Bidi algorithm on a given paragraph, as defined in the
 * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>,
 * version 13,
 * also described in The Unicode Standard, Version 4.0 .<p>
 *
 * This method takes a paragraph of text and computes the
 * left-right-directionality of each character. The text should not
 * contain any Unicode block separators.<p>
 *
 * The RUN_DIRECTION attribute in the text, if present, determines the base
 * direction (left-to-right or right-to-left). If not present, the base
 * direction is computed using the Unicode Bidirectional Algorithm,
 * defaulting to left-to-right if there are no strong directional characters
 * in the text. This attribute, if present, must be applied to all the text
 * in the paragraph.<p>
 *
 * The BIDI_EMBEDDING attribute in the text, if present, represents
 * embedding level information. Negative values from -1 to -62 indicate
 * overrides at the absolute value of the level. Positive values from 1 to
 * 62 indicate embeddings. Where values are zero or not defined, the base
 * embedding level as determined by the base direction is assumed.<p>
 *
 * The NUMERIC_SHAPING attribute in the text, if present, converts European
 * digits to other decimal digits before running the bidi algorithm. This
 * attribute, if present, must be applied to all the text in the paragraph.
 *
 * If the entire text is all of the same directionality, then
 * the method may not perform all the steps described by the algorithm,
 * i.e., some levels may not be the same as if all steps were performed.
 * This is not relevant for unidirectional text.<br>
 * For example, in pure LTR text with numbers the numbers would get
 * a resolved level of 2 higher than the surrounding text according to
 * the algorithm. This implementation may set all resolved levels to
 * the same value in such a case.<p>
 *
 * @param paragraph a paragraph of text with optional character and
 *        paragraph attribute information
 * @stable ICU 3.8
 */
public void setPara(AttributedCharacterIterator paragraph)
{
    byte paraLvl;
    char ch = paragraph.first();
    Boolean runDirection =
        (Boolean) paragraph.getAttribute(TextAttributeConstants.RUN_DIRECTION);
    Object shaper = paragraph.getAttribute(TextAttributeConstants.NUMERIC_SHAPING);
    if (runDirection == null) {
        paraLvl = INTERNAL_LEVEL_DEFAULT_LTR;
    } else {
        paraLvl = (runDirection.equals(TextAttributeConstants.RUN_DIRECTION_LTR)) ?
                    (byte)Bidi.DIRECTION_LEFT_TO_RIGHT : (byte)Bidi.DIRECTION_RIGHT_TO_LEFT;
    }

    byte[] lvls = null;
    int len = paragraph.getEndIndex() - paragraph.getBeginIndex();
    byte[] embeddingLevels = new byte[len];
    char[] txt = new char[len];
    int i = 0;
    while (ch != AttributedCharacterIterator.DONE) {
        txt[i] = ch;
        Integer embedding =
            (Integer) paragraph.getAttribute(TextAttributeConstants.BIDI_EMBEDDING);
        if (embedding != null) {
            byte level = embedding.byteValue();
            if (level == 0) {
                /* no-op */
            } else if (level < 0) {
                lvls = embeddingLevels;
                embeddingLevels[i] = (byte)((0 - level) | INTERNAL_LEVEL_OVERRIDE);
            } else {
                lvls = embeddingLevels;
                embeddingLevels[i] = level;
            }
        }
        ch = paragraph.next();
        ++i;
    }

    if (shaper != null) {
        NumericShapings.shape(shaper, txt, 0, len);
    }
    setPara(txt, paraLvl, lvls);
}
 
Example 20
Source File: getRunStartLimitTest.java    From jdk8u_jdk with GNU General Public License v2.0 4 votes vote down vote up
public static void main(String[] args) throws Exception {

        String text = "Hello world";
        AttributedString as = new AttributedString(text);

        // add non-Annotation attributes
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_LIGHT,
                        0,
                        3);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_BOLD,
                        3,
                        5);
        as.addAttribute(TextAttribute.WEIGHT,
                        TextAttribute.WEIGHT_EXTRABOLD,
                        5,
                        text.length());

        // add Annotation attributes
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_EXTENDED),
                        0,
                        3);
        as.addAttribute(TextAttribute.WIDTH,
                        new Annotation(TextAttribute.WIDTH_CONDENSED),
                        3,
                        4);

        AttributedCharacterIterator aci = as.getIterator(null, 2, 4);

        aci.first();
        int runStart = aci.getRunStart();
        if (runStart != 2) {
            throw new Exception("1st run start is wrong. ("+runStart+" should be 2.)");
        }

        int runLimit = aci.getRunLimit();
        if (runLimit != 3) {
            throw new Exception("1st run limit is wrong. ("+runLimit+" should be 3.)");
        }

        Object value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_LIGHT) {
            throw new Exception("1st run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_LIGHT+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (value != null) {
            throw new Exception("1st run annotation is wrong. ("
                                +value+" should be null.)");
        }

        aci.setIndex(runLimit);
        runStart = aci.getRunStart();
        if (runStart != 3) {
            throw new Exception("2nd run start is wrong. ("+runStart+" should be 3.)");
        }

        runLimit = aci.getRunLimit();
        if (runLimit != 4) {
            throw new Exception("2nd run limit is wrong. ("+runLimit+" should be 4.)");
        }
        value = aci.getAttribute(TextAttribute.WEIGHT);
        if (value != TextAttribute.WEIGHT_BOLD) {
            throw new Exception("2nd run attribute is wrong. ("
                                +value+" should be "+TextAttribute.WEIGHT_BOLD+".)");
        }

        value = aci.getAttribute(TextAttribute.WIDTH);
        if (!(value instanceof Annotation)
            || (((Annotation)value).getValue() !=  TextAttribute.WIDTH_CONDENSED)) {
            throw new Exception("2nd run annotation is wrong. (" + value + " should be "
                                + new Annotation(TextAttribute.WIDTH_CONDENSED)+".)");
        }
    }