AttributedString.java revision 2362
0N/A * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 873N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * or visit www.oracle.com if you need additional information or have any 0N/A * An AttributedString holds text and related attribute information. It 0N/A * may be used as the actual data storage in some cases where a text 3012N/A * reader wants to access attributed text through the AttributedCharacterIterator 1083N/A * attributes on a given character can have the same key. 1083N/A * <p>The values for an attribute are immutable, or must not be mutated 1083N/A * by clients or storage. They are always passed by reference, and not 3090N/A * @see AttributedCharacterIterator 233N/A // since there are no vectors of int, we have to use arrays. 712N/A // We allocate them in chunks of 10 elements so we don't have to allocate all the time. 0N/A // field holding the text 0N/A // fields holding run attribute information 712N/A // run attributes are organized by run 0N/A int runCount;
// actual number of runs, <= runArraySize 0N/A * Constructs an AttributedString instance with the given 0N/A * AttributedCharacterIterators. 0N/A * @param iterators AttributedCharacterIterators to construct 0N/A * AttributedString from. 0N/A * @throws NullPointerException if iterators is null 2033N/A // Build the String contents 567N/A // Determine the runs, creating a new run when the attributes 729N/A * Constructs an AttributedString instance with the given text. 729N/A * @param text The text for this attributed string. 729N/A * @exception NullPointerException if <code>text</code> is null. 1008N/A * Constructs an AttributedString instance with the given text and attributes. 1008N/A * @param text The text for this attributed string. 1008N/A * @param attributes The attributes that apply to the entire string. 1008N/A * @exception NullPointerException if <code>text</code> or 3214N/A * <code>attributes</code> is null. 3214N/A * @exception IllegalArgumentException if the text has length 0 2086N/A * and the attributes parameter is not an empty Map (attributes 2086N/A * cannot be applied to a 0-length range). 1177N/A * Constructs an AttributedString instance with the given attributed 1177N/A * text represented by AttributedCharacterIterator. 0N/A * @param text The text for this attributed string. 0N/A * @exception NullPointerException if <code>text</code> is null. 0N/A // If performance is critical, this constructor should be 0N/A // implemented here rather than invoking the constructor for a 3090N/A // subrange. We can avoid some range checking in the loops. 2086N/A * Constructs an AttributedString instance with the subrange of 2086N/A * the given attributed text represented by 2086N/A * AttributedCharacterIterator. If the given range produces an 2086N/A * empty text, all attributes will be discarded. Note that any 2086N/A * attributes wrapped by an Annotation object are discarded for a 2086N/A * subrange of the original attribute range. 2086N/A * @param text The text for this attributed string. 2086N/A * @param beginIndex Index of the first character of the range. 2086N/A * @param endIndex Index of the character following the last character 2086N/A * @exception NullPointerException if <code>text</code> is null. 2086N/A * @exception IllegalArgumentException if the subrange given by 2086N/A * beginIndex and endIndex is out of the text range. 2086N/A * @see java.text.Annotation 2086N/A * Constructs an AttributedString instance with the subrange of 2086N/A * the given attributed text represented by 2086N/A * AttributedCharacterIterator. Only attributes that match the 2086N/A * given attributes will be incorporated into the instance. If the 2086N/A * given range produces an empty text, all attributes will be 2086N/A * discarded. Note that any attributes wrapped by an Annotation 2086N/A * object are discarded for a subrange of the original attribute 2284N/A * @param text The text for this attributed string. 2284N/A * @param beginIndex Index of the first character of the range. 2284N/A * @param endIndex Index of the character following the last character 2086N/A * @param attributes Specifies attributes to be extracted 2086N/A * from the text. If null is specified, all available attributes will 2086N/A * @exception NullPointerException if <code>text</code> is null. 2086N/A * @exception IllegalArgumentException if the subrange given by 2086N/A * beginIndex and endIndex is out of the text range. 2086N/A * @see java.text.Annotation 2086N/A // Validate the given subrange 2086N/A // Select attribute keys to be taken care of 0N/A // Get and set attribute runs for each attribute name. Need to 2342N/A // scan from the top of the text so that we can discard any 1008N/A // Annotation that is no longer applied to a subset text segment. 1273N/A // if the run is beyond the given (subset) range, we 1273N/A // don't need to process further. 1273N/A // attribute is applied to any subrange 1273N/A * Adds an attribute to the entire string. 1960N/A * @param attribute the attribute key 1273N/A * @param value the value of the attribute; may be null 1273N/A * @exception NullPointerException if <code>attribute</code> is null. 0N/A * @exception IllegalArgumentException if the AttributedString has length 0 121N/A * (attributes cannot be applied to a 0-length range). 0N/A * Adds an attribute to a subrange of the string. 0N/A * @param attribute the attribute key 0N/A * @param value The value of the attribute. May be null. 0N/A * @param beginIndex Index of the first character of the range. 984N/A * @param endIndex Index of the character following the last character of the range. 984N/A * @exception NullPointerException if <code>attribute</code> is null. 984N/A * @exception IllegalArgumentException if beginIndex is less then 0, endIndex is 984N/A * greater than the length of the string, or beginIndex and endIndex together don't 902N/A * define a non-empty subrange of the string. 0N/A * Adds a set of attributes to a subrange of the string. 0N/A * @param attributes The attributes to be added to the string. 0N/A * @param beginIndex Index of the first character of the range. 729N/A * @param endIndex Index of the character following the last 729N/A * character of the range. 729N/A * @exception NullPointerException if <code>attributes</code> is null. 729N/A * @exception IllegalArgumentException if beginIndex is less then 729N/A * 0, endIndex is greater than the length of the string, or 729N/A * beginIndex and endIndex together don't define a non-empty 729N/A * subrange of the string and the attributes parameter is not an 1344N/A // make sure we have run attribute data vectors 1344N/A // break up runs if necessary 109N/A // make sure we have run attribute data vectors 1344N/A // break up runs if necessary 109N/A // use temporary variables so things remain consistent in case of an exception 1344N/A // ensure there's a run break at offset, return the index of the run 729N/A * Ensures there is a run break at offset, returning the index of 729N/A * the run. If this results in splitting a run, two things can happen: 729N/A * <li>If copyAttrs is true, the attributes from the existing run 729N/A * will be placed in both of the newly created runs. 1344N/A * <li>If copyAttrs is false, the attributes from the existing run 729N/A * will NOT be copied to the run to the right (>= offset) of the break, 729N/A * but will exist on the run to the left (< offset). 0N/A // search for the run index where this offset should be 2086N/A // if the offset is at a run start already, we're done 2086N/A // we'll have to break up a run 2086N/A // first, make sure we have enough space in our arrays 712N/A // make copies of the attribute information of the old run that the new one used to be part of 730N/A // use temporary variables so things remain consistent in case of an exception 114N/A // now actually break up the run 0N/A int keyValueIndex = -
1;
// index of key and value in our vectors; assume we don't have an entry yet 0N/A // check whether we have an entry already 0N/A // update existing entry 984N/A * Creates an AttributedCharacterIterator instance that provides access to the entire contents of 1177N/A * @return An iterator providing access to the text and its attributes. 902N/A * Creates an AttributedCharacterIterator instance that provides access to 902N/A * selected contents of this string. 902N/A * Information about attributes not listed in attributes that the 902N/A * implementor may have need not be made accessible through the iterator. 902N/A * If the list is null, all available attribute information should be made 902N/A * @param attributes a list of attributes that the client is interested in 902N/A * @return an iterator providing access to the entire text and its selected attributes 902N/A * Creates an AttributedCharacterIterator instance that provides access to 1177N/A * selected contents of this string. 567N/A * Information about attributes not listed in attributes that the 1559N/A * implementor may have need not be made accessible through the iterator. 567N/A * If the list is null, all available attribute information should be made 1210N/A * @param attributes a list of attributes that the client is interested in 1210N/A * @param beginIndex the index of the first character 1210N/A * @param endIndex the index of the character following the last character 1210N/A * @return an iterator providing access to the text and its attributes 1210N/A * @exception IllegalArgumentException if beginIndex is less then 0, 1210N/A * endIndex is greater than the length of the string, or beginIndex is 1083N/A // all (with the exception of length) reading operations are private, 1008N/A // since AttributedString instances are accessed through iterators. 1008N/A // length is package private so that CharacterIteratorFieldDelegate can 1210N/A // access it without creating an AttributedCharacterIterator. 567N/A // gets an attribute value, but returns an annotation only if it's range does not extend outside the range beginIndex..endIndex 567N/A // need to check whether the annotation's range extends outside the iterator's range 2710N/A // annotation's range starts before iterator's range 0N/A // annotation's range ends after iterator's range 0N/A // annotation's range is subrange of iterator's range, 0N/A // so we can return the value 1362N/A // returns whether all specified attributes have equal values in the runs with the given indices 0N/A // returns whether the two objects are either both null or equal 0N/A * Appends the contents of the CharacterIterator iterator into the 2046N/A * Sets the attributes for the range from offset to the next run break 0N/A * (typically the end of the text) to the ones specified in attrs. 0N/A * This is only meant to be called from the constructor! 1210N/A * Returns true if the attributes specified in last and attrs differ. 1008N/A // the iterator class associated with this string class 1008N/A // note on synchronization: 1008N/A // we don't synchronize on the iterator, assuming that an iterator is only used in one thread. 1008N/A // we do synchronize access to the AttributedString however, since it's more likely to be shared between threads. 1083N/A // start and end index for our iteration 1008N/A // attributes that our client is interested in 1008N/A // the current index for our iteration 1008N/A // invariant: beginIndex <= currentIndex <= endIndex 1008N/A // information about the run that includes currentIndex 3214N/A // Object methods. See documentation in that class. 3214N/A // CharacterIterator methods. See documentation in that interface. 2556N/A // AttributedCharacterIterator methods. See documentation in that interface. 2556N/A // ??? would be nice to return null, but current spec doesn't allow it 2556N/A // returning Hashtable saves AttributeMap from dealing with emptiness 2556N/A // ??? This should screen out attribute keys that aren't relevant to the client 2556N/A // ??? would be nice to return null, but current spec doesn't allow it 2556N/A // returning HashSet saves us from dealing with emptiness 2556N/A // ??? should try to create this only once, then update if necessary, 2556N/A // and give callers read-only view 499N/A // set the current index, update information about the current run if necessary, 0N/A // return the character at the current index 3069N/A // update the information about the current run 3069N/A // the map class associated with this string class, giving access to the attributes of one run