100 while (index < end) {
101 iterator.setIndex(index);
102
103 Map<Attribute,Object> attrs = iterator.getAttributes();
104
105 if (mapsDiffer(last, attrs)) {
106 setAttributes(attrs, index - start + offset);
107 }
108 last = attrs;
109 index = iterator.getRunLimit();
110 }
111 offset += (end - start);
112 }
113 }
114 }
115 }
116
117 /**
118 * Constructs an AttributedString instance with the given text.
119 * @param text The text for this attributed string.
120 * @exception NullPointerException if <code>text</code> is null.
121 */
122 public AttributedString(String text) {
123 if (text == null) {
124 throw new NullPointerException();
125 }
126 this.text = text;
127 }
128
129 /**
130 * Constructs an AttributedString instance with the given text and attributes.
131 * @param text The text for this attributed string.
132 * @param attributes The attributes that apply to the entire string.
133 * @exception NullPointerException if <code>text</code> or
134 * <code>attributes</code> is null.
135 * @exception IllegalArgumentException if the text has length 0
136 * and the attributes parameter is not an empty Map (attributes
137 * cannot be applied to a 0-length range).
138 */
139 public AttributedString(String text,
140 Map<? extends Attribute, ?> attributes)
141 {
142 if (text == null || attributes == null) {
143 throw new NullPointerException();
144 }
145 this.text = text;
146
147 if (text.isEmpty()) {
148 if (attributes.isEmpty())
149 return;
150 throw new IllegalArgumentException("Can't add attribute to 0-length text");
151 }
152
153 int attributeCount = attributes.size();
154 if (attributeCount > 0) {
155 createRunAttributeDataVectors();
156 Vector<Attribute> newRunAttributes = new Vector<>(attributeCount);
157 Vector<Object> newRunAttributeValues = new Vector<>(attributeCount);
158 runAttributes[0] = newRunAttributes;
159 runAttributeValues[0] = newRunAttributeValues;
160
161 Iterator<? extends Map.Entry<? extends Attribute, ?>> iterator = attributes.entrySet().iterator();
162 while (iterator.hasNext()) {
163 Map.Entry<? extends Attribute, ?> entry = iterator.next();
164 newRunAttributes.addElement(entry.getKey());
165 newRunAttributeValues.addElement(entry.getValue());
166 }
167 }
168 }
169
170 /**
171 * Constructs an AttributedString instance with the given attributed
172 * text represented by AttributedCharacterIterator.
173 * @param text The text for this attributed string.
174 * @exception NullPointerException if <code>text</code> is null.
175 */
176 public AttributedString(AttributedCharacterIterator text) {
177 // If performance is critical, this constructor should be
178 // implemented here rather than invoking the constructor for a
179 // subrange. We can avoid some range checking in the loops.
180 this(text, text.getBeginIndex(), text.getEndIndex(), null);
181 }
182
183 /**
184 * Constructs an AttributedString instance with the subrange of
185 * the given attributed text represented by
186 * AttributedCharacterIterator. If the given range produces an
187 * empty text, all attributes will be discarded. Note that any
188 * attributes wrapped by an Annotation object are discarded for a
189 * subrange of the original attribute range.
190 *
191 * @param text The text for this attributed string.
192 * @param beginIndex Index of the first character of the range.
193 * @param endIndex Index of the character following the last character
194 * of the range.
195 * @exception NullPointerException if <code>text</code> is null.
196 * @exception IllegalArgumentException if the subrange given by
197 * beginIndex and endIndex is out of the text range.
198 * @see java.text.Annotation
199 */
200 public AttributedString(AttributedCharacterIterator text,
201 int beginIndex,
202 int endIndex) {
203 this(text, beginIndex, endIndex, null);
204 }
205
206 /**
207 * Constructs an AttributedString instance with the subrange of
208 * the given attributed text represented by
209 * AttributedCharacterIterator. Only attributes that match the
210 * given attributes will be incorporated into the instance. If the
211 * given range produces an empty text, all attributes will be
212 * discarded. Note that any attributes wrapped by an Annotation
213 * object are discarded for a subrange of the original attribute
214 * range.
215 *
216 * @param text The text for this attributed string.
217 * @param beginIndex Index of the first character of the range.
218 * @param endIndex Index of the character following the last character
219 * of the range.
220 * @param attributes Specifies attributes to be extracted
221 * from the text. If null is specified, all available attributes will
222 * be used.
223 * @exception NullPointerException if <code>text</code> is null.
224 * @exception IllegalArgumentException if the subrange given by
225 * beginIndex and endIndex is out of the text range.
226 * @see java.text.Annotation
227 */
228 public AttributedString(AttributedCharacterIterator text,
229 int beginIndex,
230 int endIndex,
231 Attribute[] attributes) {
232 if (text == null) {
233 throw new NullPointerException();
234 }
235
236 // Validate the given subrange
237 int textBeginIndex = text.getBeginIndex();
238 int textEndIndex = text.getEndIndex();
239 if (beginIndex < textBeginIndex || endIndex > textEndIndex || beginIndex > endIndex)
240 throw new IllegalArgumentException("Invalid substring range");
241
242 // Copy the given string
243 StringBuilder textBuilder = new StringBuilder();
244 text.setIndex(beginIndex);
290 // attribute is applied to any subrange
291 if (start < beginIndex)
292 start = beginIndex;
293 if (limit > endIndex)
294 limit = endIndex;
295 if (start != limit) {
296 addAttribute(attributeKey, value, start - beginIndex, limit - beginIndex);
297 }
298 }
299 }
300 }
301 text.setIndex(limit);
302 }
303 }
304 }
305
306 /**
307 * Adds an attribute to the entire string.
308 * @param attribute the attribute key
309 * @param value the value of the attribute; may be null
310 * @exception NullPointerException if <code>attribute</code> is null.
311 * @exception IllegalArgumentException if the AttributedString has length 0
312 * (attributes cannot be applied to a 0-length range).
313 */
314 public void addAttribute(Attribute attribute, Object value) {
315
316 if (attribute == null) {
317 throw new NullPointerException();
318 }
319
320 int len = length();
321 if (len == 0) {
322 throw new IllegalArgumentException("Can't add attribute to 0-length text");
323 }
324
325 addAttributeImpl(attribute, value, 0, len);
326 }
327
328 /**
329 * Adds an attribute to a subrange of the string.
330 * @param attribute the attribute key
331 * @param value The value of the attribute. May be null.
332 * @param beginIndex Index of the first character of the range.
333 * @param endIndex Index of the character following the last character of the range.
334 * @exception NullPointerException if <code>attribute</code> is null.
335 * @exception IllegalArgumentException if beginIndex is less than 0, endIndex is
336 * greater than the length of the string, or beginIndex and endIndex together don't
337 * define a non-empty subrange of the string.
338 */
339 public void addAttribute(Attribute attribute, Object value,
340 int beginIndex, int endIndex) {
341
342 if (attribute == null) {
343 throw new NullPointerException();
344 }
345
346 if (beginIndex < 0 || endIndex > length() || beginIndex >= endIndex) {
347 throw new IllegalArgumentException("Invalid substring range");
348 }
349
350 addAttributeImpl(attribute, value, beginIndex, endIndex);
351 }
352
353 /**
354 * Adds a set of attributes to a subrange of the string.
355 * @param attributes The attributes to be added to the string.
356 * @param beginIndex Index of the first character of the range.
357 * @param endIndex Index of the character following the last
358 * character of the range.
359 * @exception NullPointerException if <code>attributes</code> is null.
360 * @exception IllegalArgumentException if beginIndex is less than
361 * 0, endIndex is greater than the length of the string, or
362 * beginIndex and endIndex together don't define a non-empty
363 * subrange of the string and the attributes parameter is not an
364 * empty Map.
365 */
366 public void addAttributes(Map<? extends Attribute, ?> attributes,
367 int beginIndex, int endIndex)
368 {
369 if (attributes == null) {
370 throw new NullPointerException();
371 }
372
373 if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) {
374 throw new IllegalArgumentException("Invalid substring range");
375 }
376 if (beginIndex == endIndex) {
377 if (attributes.isEmpty())
378 return;
379 throw new IllegalArgumentException("Can't add attribute to 0-length text");
380 }
563 *
564 * @param attributes a list of attributes that the client is interested in
565 * @return an iterator providing access to the entire text and its selected attributes
566 */
567 public AttributedCharacterIterator getIterator(Attribute[] attributes) {
568 return getIterator(attributes, 0, length());
569 }
570
571 /**
572 * Creates an AttributedCharacterIterator instance that provides access to
573 * selected contents of this string.
574 * Information about attributes not listed in attributes that the
575 * implementor may have need not be made accessible through the iterator.
576 * If the list is null, all available attribute information should be made
577 * accessible.
578 *
579 * @param attributes a list of attributes that the client is interested in
580 * @param beginIndex the index of the first character
581 * @param endIndex the index of the character following the last character
582 * @return an iterator providing access to the text and its attributes
583 * @exception IllegalArgumentException if beginIndex is less than 0,
584 * endIndex is greater than the length of the string, or beginIndex is
585 * greater than endIndex.
586 */
587 public AttributedCharacterIterator getIterator(Attribute[] attributes, int beginIndex, int endIndex) {
588 return new AttributedStringIterator(attributes, beginIndex, endIndex);
589 }
590
591 // all (with the exception of length) reading operations are private,
592 // since AttributedString instances are accessed through iterators.
593
594 // length is package private so that CharacterIteratorFieldDelegate can
595 // access it without creating an AttributedCharacterIterator.
596 int length() {
597 return text.length();
598 }
599
600 private char charAt(int index) {
601 return text.charAt(index);
602 }
603
|
100 while (index < end) {
101 iterator.setIndex(index);
102
103 Map<Attribute,Object> attrs = iterator.getAttributes();
104
105 if (mapsDiffer(last, attrs)) {
106 setAttributes(attrs, index - start + offset);
107 }
108 last = attrs;
109 index = iterator.getRunLimit();
110 }
111 offset += (end - start);
112 }
113 }
114 }
115 }
116
117 /**
118 * Constructs an AttributedString instance with the given text.
119 * @param text The text for this attributed string.
120 * @throws NullPointerException if <code>text</code> is null.
121 */
122 public AttributedString(String text) {
123 if (text == null) {
124 throw new NullPointerException();
125 }
126 this.text = text;
127 }
128
129 /**
130 * Constructs an AttributedString instance with the given text and attributes.
131 * @param text The text for this attributed string.
132 * @param attributes The attributes that apply to the entire string.
133 * @throws NullPointerException if <code>text</code> or
134 * <code>attributes</code> is null.
135 * @throws IllegalArgumentException if the text has length 0
136 * and the attributes parameter is not an empty Map (attributes
137 * cannot be applied to a 0-length range).
138 */
139 public AttributedString(String text,
140 Map<? extends Attribute, ?> attributes)
141 {
142 if (text == null || attributes == null) {
143 throw new NullPointerException();
144 }
145 this.text = text;
146
147 if (text.isEmpty()) {
148 if (attributes.isEmpty())
149 return;
150 throw new IllegalArgumentException("Can't add attribute to 0-length text");
151 }
152
153 int attributeCount = attributes.size();
154 if (attributeCount > 0) {
155 createRunAttributeDataVectors();
156 Vector<Attribute> newRunAttributes = new Vector<>(attributeCount);
157 Vector<Object> newRunAttributeValues = new Vector<>(attributeCount);
158 runAttributes[0] = newRunAttributes;
159 runAttributeValues[0] = newRunAttributeValues;
160
161 Iterator<? extends Map.Entry<? extends Attribute, ?>> iterator = attributes.entrySet().iterator();
162 while (iterator.hasNext()) {
163 Map.Entry<? extends Attribute, ?> entry = iterator.next();
164 newRunAttributes.addElement(entry.getKey());
165 newRunAttributeValues.addElement(entry.getValue());
166 }
167 }
168 }
169
170 /**
171 * Constructs an AttributedString instance with the given attributed
172 * text represented by AttributedCharacterIterator.
173 * @param text The text for this attributed string.
174 * @throws NullPointerException if <code>text</code> is null.
175 */
176 public AttributedString(AttributedCharacterIterator text) {
177 // If performance is critical, this constructor should be
178 // implemented here rather than invoking the constructor for a
179 // subrange. We can avoid some range checking in the loops.
180 this(text, text.getBeginIndex(), text.getEndIndex(), null);
181 }
182
183 /**
184 * Constructs an AttributedString instance with the subrange of
185 * the given attributed text represented by
186 * AttributedCharacterIterator. If the given range produces an
187 * empty text, all attributes will be discarded. Note that any
188 * attributes wrapped by an Annotation object are discarded for a
189 * subrange of the original attribute range.
190 *
191 * @param text The text for this attributed string.
192 * @param beginIndex Index of the first character of the range.
193 * @param endIndex Index of the character following the last character
194 * of the range.
195 * @throws NullPointerException if <code>text</code> is null.
196 * @throws IllegalArgumentException if the subrange given by
197 * beginIndex and endIndex is out of the text range.
198 * @see java.text.Annotation
199 */
200 public AttributedString(AttributedCharacterIterator text,
201 int beginIndex,
202 int endIndex) {
203 this(text, beginIndex, endIndex, null);
204 }
205
206 /**
207 * Constructs an AttributedString instance with the subrange of
208 * the given attributed text represented by
209 * AttributedCharacterIterator. Only attributes that match the
210 * given attributes will be incorporated into the instance. If the
211 * given range produces an empty text, all attributes will be
212 * discarded. Note that any attributes wrapped by an Annotation
213 * object are discarded for a subrange of the original attribute
214 * range.
215 *
216 * @param text The text for this attributed string.
217 * @param beginIndex Index of the first character of the range.
218 * @param endIndex Index of the character following the last character
219 * of the range.
220 * @param attributes Specifies attributes to be extracted
221 * from the text. If null is specified, all available attributes will
222 * be used.
223 * @throws NullPointerException if <code>text</code> is null.
224 * @throws IllegalArgumentException if the subrange given by
225 * beginIndex and endIndex is out of the text range.
226 * @see java.text.Annotation
227 */
228 public AttributedString(AttributedCharacterIterator text,
229 int beginIndex,
230 int endIndex,
231 Attribute[] attributes) {
232 if (text == null) {
233 throw new NullPointerException();
234 }
235
236 // Validate the given subrange
237 int textBeginIndex = text.getBeginIndex();
238 int textEndIndex = text.getEndIndex();
239 if (beginIndex < textBeginIndex || endIndex > textEndIndex || beginIndex > endIndex)
240 throw new IllegalArgumentException("Invalid substring range");
241
242 // Copy the given string
243 StringBuilder textBuilder = new StringBuilder();
244 text.setIndex(beginIndex);
290 // attribute is applied to any subrange
291 if (start < beginIndex)
292 start = beginIndex;
293 if (limit > endIndex)
294 limit = endIndex;
295 if (start != limit) {
296 addAttribute(attributeKey, value, start - beginIndex, limit - beginIndex);
297 }
298 }
299 }
300 }
301 text.setIndex(limit);
302 }
303 }
304 }
305
306 /**
307 * Adds an attribute to the entire string.
308 * @param attribute the attribute key
309 * @param value the value of the attribute; may be null
310 * @throws NullPointerException if <code>attribute</code> is null.
311 * @throws IllegalArgumentException if the AttributedString has length 0
312 * (attributes cannot be applied to a 0-length range).
313 */
314 public void addAttribute(Attribute attribute, Object value) {
315
316 if (attribute == null) {
317 throw new NullPointerException();
318 }
319
320 int len = length();
321 if (len == 0) {
322 throw new IllegalArgumentException("Can't add attribute to 0-length text");
323 }
324
325 addAttributeImpl(attribute, value, 0, len);
326 }
327
328 /**
329 * Adds an attribute to a subrange of the string.
330 * @param attribute the attribute key
331 * @param value The value of the attribute. May be null.
332 * @param beginIndex Index of the first character of the range.
333 * @param endIndex Index of the character following the last character of the range.
334 * @throws NullPointerException if <code>attribute</code> is null.
335 * @throws IllegalArgumentException if beginIndex is less than 0, endIndex is
336 * greater than the length of the string, or beginIndex and endIndex together don't
337 * define a non-empty subrange of the string.
338 */
339 public void addAttribute(Attribute attribute, Object value,
340 int beginIndex, int endIndex) {
341
342 if (attribute == null) {
343 throw new NullPointerException();
344 }
345
346 if (beginIndex < 0 || endIndex > length() || beginIndex >= endIndex) {
347 throw new IllegalArgumentException("Invalid substring range");
348 }
349
350 addAttributeImpl(attribute, value, beginIndex, endIndex);
351 }
352
353 /**
354 * Adds a set of attributes to a subrange of the string.
355 * @param attributes The attributes to be added to the string.
356 * @param beginIndex Index of the first character of the range.
357 * @param endIndex Index of the character following the last
358 * character of the range.
359 * @throws NullPointerException if <code>attributes</code> is null.
360 * @throws IllegalArgumentException if beginIndex is less than
361 * 0, endIndex is greater than the length of the string, or
362 * beginIndex and endIndex together don't define a non-empty
363 * subrange of the string and the attributes parameter is not an
364 * empty Map.
365 */
366 public void addAttributes(Map<? extends Attribute, ?> attributes,
367 int beginIndex, int endIndex)
368 {
369 if (attributes == null) {
370 throw new NullPointerException();
371 }
372
373 if (beginIndex < 0 || endIndex > length() || beginIndex > endIndex) {
374 throw new IllegalArgumentException("Invalid substring range");
375 }
376 if (beginIndex == endIndex) {
377 if (attributes.isEmpty())
378 return;
379 throw new IllegalArgumentException("Can't add attribute to 0-length text");
380 }
563 *
564 * @param attributes a list of attributes that the client is interested in
565 * @return an iterator providing access to the entire text and its selected attributes
566 */
567 public AttributedCharacterIterator getIterator(Attribute[] attributes) {
568 return getIterator(attributes, 0, length());
569 }
570
571 /**
572 * Creates an AttributedCharacterIterator instance that provides access to
573 * selected contents of this string.
574 * Information about attributes not listed in attributes that the
575 * implementor may have need not be made accessible through the iterator.
576 * If the list is null, all available attribute information should be made
577 * accessible.
578 *
579 * @param attributes a list of attributes that the client is interested in
580 * @param beginIndex the index of the first character
581 * @param endIndex the index of the character following the last character
582 * @return an iterator providing access to the text and its attributes
583 * @throws IllegalArgumentException if beginIndex is less than 0,
584 * endIndex is greater than the length of the string, or beginIndex is
585 * greater than endIndex.
586 */
587 public AttributedCharacterIterator getIterator(Attribute[] attributes, int beginIndex, int endIndex) {
588 return new AttributedStringIterator(attributes, beginIndex, endIndex);
589 }
590
591 // all (with the exception of length) reading operations are private,
592 // since AttributedString instances are accessed through iterators.
593
594 // length is package private so that CharacterIteratorFieldDelegate can
595 // access it without creating an AttributedCharacterIterator.
596 int length() {
597 return text.length();
598 }
599
600 private char charAt(int index) {
601 return text.charAt(index);
602 }
603
|