public AttributedString(AttributedCharacterIterator text,int beginIndex,int endIndex,Attribute[] attributes){
  if (text == null) {
    throw new NullPointerException();
  }
  int textBeginIndex=text.getBeginIndex();
  int textEndIndex=text.getEndIndex();
  if (beginIndex < textBeginIndex || endIndex > textEndIndex || beginIndex > endIndex)   throw new IllegalArgumentException("Invalid substring range");
  StringBuffer textBuffer=new StringBuffer();
  text.setIndex(beginIndex);
  for (char c=text.current(); text.getIndex() < endIndex; c=text.next())   textBuffer.append(c);
  this.text=textBuffer.toString();
  if (beginIndex == endIndex)   return;
  HashSet<Attribute> keys=new HashSet<>();
  if (attributes == null) {
    keys.addAll(text.getAllAttributeKeys());
  }
 else {
    for (int i=0; i < attributes.length; i++)     keys.add(attributes[i]);
    keys.retainAll(text.getAllAttributeKeys());
  }
  if (keys.isEmpty())   return;
  Iterator<Attribute> itr=keys.iterator();
  while (itr.hasNext()) {
    Attribute attributeKey=itr.next();
    text.setIndex(textBeginIndex);
    while (text.getIndex() < endIndex) {
      int start=text.getRunStart(attributeKey);
      int limit=text.getRunLimit(attributeKey);
      Object value=text.getAttribute(attributeKey);
      if (value != null) {
        if (value instanceof Annotation) {
          if (start >= beginIndex && limit <= endIndex) {
            addAttribute(attributeKey,value,start - beginIndex,limit - beginIndex);
          }
 else {
            if (limit > endIndex)             break;
          }
        }
 else {
          if (start >= endIndex)           break;
          if (limit > beginIndex) {
            if (start < beginIndex)             start=beginIndex;
            if (limit > endIndex)             limit=endIndex;
            if (start != limit) {
              addAttribute(attributeKey,value,start - beginIndex,limit - beginIndex);
            }
          }
        }
      }
      text.setIndex(limit);
    }
  }
}

public AttributedString ( AttributedCharacterIterator text , int beginIndex , int endIndex , Attribute [ ] attributes ) { if ( text == null ) { throw new NullPointerException ( ) ; } int textBeginIndex = text . getBeginIndex ( ) ; int textEndIndex = text . getEndIndex ( ) ; if ( beginIndex < textBeginIndex || endIndex > textEndIndex || beginIndex > endIndex ) throw new IllegalArgumentException ( "Invalid substring range" ) ; StringBuffer textBuffer = new StringBuffer ( ) ; text . setIndex ( beginIndex ) ; for ( char c = text . current ( ) ; text . getIndex ( ) < endIndex ; c = text . next ( ) ) textBuffer . append ( c ) ; this . text = textBuffer . toString ( ) ; if ( beginIndex == endIndex ) return ; HashSet < Attribute > keys = new HashSet < > ( ) ; if ( attributes == null ) { keys . addAll ( text . getAllAttributeKeys ( ) ) ; } else { for ( int i = 0 ; i < attributes . length ; i ++ ) keys . add ( attributes [ i ] ) ; keys . retainAll ( text . getAllAttributeKeys ( ) ) ; } if ( keys . isEmpty ( ) ) return ; Iterator < Attribute > itr = keys . iterator ( ) ; while ( itr . hasNext ( ) ) { Attribute attributeKey = itr . next ( ) ; text . setIndex ( textBeginIndex ) ; while ( text . getIndex ( ) < endIndex ) { int start = text . getRunStart ( attributeKey ) ; int limit = text . getRunLimit ( attributeKey ) ; Object value = text . getAttribute ( attributeKey ) ; if ( value != null ) { if ( value instanceof Annotation ) { if ( start >= beginIndex && limit <= endIndex ) { addAttribute ( attributeKey , value , start - beginIndex , limit - beginIndex ) ; } else { if ( limit > endIndex ) break ; } } else { if ( start >= endIndex ) break ; if ( limit > beginIndex ) { if ( start < beginIndex ) start = beginIndex ; if ( limit > endIndex ) limit = endIndex ; if ( start != limit ) { addAttribute ( attributeKey , value , start - beginIndex , limit - beginIndex ) ; } } } } text . setIndex ( limit ) ; } } }
constructs an attributedstring instance with the subrange of the given attributed text represented by attributedcharacteriterator . only attributes that match the given attributes will be incorporated into the instance . if the given range produces an empty text , all attributes will be discarded . note that any attributes wrapped by an annotation object are discarded for a subrange of the original attribute range .
