⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attributedstring.java

📁 java源代码 请看看啊 提点宝贵的意见
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            int beginIndex, int endIndex) {                // make sure we have run attribute data vectors        if (runCount == 0) {            createRunAttributeDataVectors();        }                // break up runs if necessary        int beginRunIndex = ensureRunBreak(beginIndex);        int endRunIndex = ensureRunBreak(endIndex);                addAttributeRunData(attribute, value, beginRunIndex, endRunIndex);    }        private final void createRunAttributeDataVectors() {        // use temporary variables so things remain consistent in case of an exception        int newRunStarts[] = new int[ARRAY_SIZE_INCREMENT];        Vector newRunAttributes[] = new Vector[ARRAY_SIZE_INCREMENT];        Vector newRunAttributeValues[] = new Vector[ARRAY_SIZE_INCREMENT];        runStarts = newRunStarts;        runAttributes = newRunAttributes;        runAttributeValues = newRunAttributeValues;        runArraySize = ARRAY_SIZE_INCREMENT;        runCount = 1; // assume initial run starting at index 0    }    // ensure there's a run break at offset, return the index of the run    private final int ensureRunBreak(int offset) {        return ensureRunBreak(offset, true);    }    /**     * Ensures there is a run break at offset, returning the index of     * the run. If this results in splitting a run, two things can happen:     * <ul>     * <li>If copyAttrs is true, the attributes from the existing run     *     will be placed in both of the newly created runs.     * <li>If copyAttrs is false, the attributes from the existing run     * will NOT be copied to the run to the right (>= offset) of the break,     * but will exist on the run to the left (< offset).     * </ul>     */    private final int ensureRunBreak(int offset, boolean copyAttrs) {        if (offset == length()) {            return runCount;        }        // search for the run index where this offset should be        int runIndex = 0;        while (runIndex < runCount && runStarts[runIndex] < offset) {            runIndex++;        }        // if the offset is at a run start already, we're done        if (runIndex < runCount && runStarts[runIndex] == offset) {            return runIndex;        }                // we'll have to break up a run        // first, make sure we have enough space in our arrays        if (runCount == runArraySize) {            int newArraySize = runArraySize + ARRAY_SIZE_INCREMENT;            int newRunStarts[] = new int[newArraySize];            Vector newRunAttributes[] = new Vector[newArraySize];            Vector newRunAttributeValues[] = new Vector[newArraySize];            for (int i = 0; i < runArraySize; i++) {                newRunStarts[i] = runStarts[i];                newRunAttributes[i] = runAttributes[i];                newRunAttributeValues[i] = runAttributeValues[i];            }            runStarts = newRunStarts;            runAttributes = newRunAttributes;            runAttributeValues = newRunAttributeValues;            runArraySize = newArraySize;        }                // make copies of the attribute information of the old run that the new one used to be part of        // use temporary variables so things remain consistent in case of an exception        Vector newRunAttributes = null;        Vector newRunAttributeValues = null;        if (copyAttrs) {            Vector oldRunAttributes = runAttributes[runIndex - 1];            Vector oldRunAttributeValues = runAttributeValues[runIndex - 1];            if (oldRunAttributes != null) {                newRunAttributes = (Vector) oldRunAttributes.clone();            }            if (oldRunAttributeValues != null) {                newRunAttributeValues = (Vector) oldRunAttributeValues.clone();            }        }                // now actually break up the run        runCount++;        for (int i = runCount - 1; i > runIndex; i--) {            runStarts[i] = runStarts[i - 1];            runAttributes[i] = runAttributes[i - 1];            runAttributeValues[i] = runAttributeValues[i - 1];        }        runStarts[runIndex] = offset;        runAttributes[runIndex] = newRunAttributes;        runAttributeValues[runIndex] = newRunAttributeValues;        return runIndex;    }    // add the attribute attribute/value to all runs where beginRunIndex <= runIndex < endRunIndex    private void addAttributeRunData(Attribute attribute, Object value,            int beginRunIndex, int endRunIndex) {        for (int i = beginRunIndex; i < endRunIndex; i++) {            int keyValueIndex = -1; // index of key and value in our vectors; assume we don't have an entry yet            if (runAttributes[i] == null) {                Vector newRunAttributes = new Vector();                Vector newRunAttributeValues = new Vector();                runAttributes[i] = newRunAttributes;                runAttributeValues[i] = newRunAttributeValues;            } else {                // check whether we have an entry already                keyValueIndex = runAttributes[i].indexOf(attribute);            }            if (keyValueIndex == -1) {                // create new entry                int oldSize = runAttributes[i].size();                runAttributes[i].addElement(attribute);                try {                    runAttributeValues[i].addElement(value);                }                catch (Exception e) {                    runAttributes[i].setSize(oldSize);                    runAttributeValues[i].setSize(oldSize);                }            } else {                // update existing entry                runAttributeValues[i].set(keyValueIndex, value);            }        }    }    /**     * Creates an AttributedCharacterIterator instance that provides access to the entire contents of     * this string.     *     * @return An iterator providing access to the text and its attributes.     */    public AttributedCharacterIterator getIterator() {        return getIterator(null, 0, length());    }    /**     * Creates an AttributedCharacterIterator instance that provides access to     * selected contents of this string.     * Information about attributes not listed in attributes that the     * implementor may have need not be made accessible through the iterator.     * If the list is null, all available attribute information should be made     * accessible.     *     * @param attributes a list of attributes that the client is interested in     * @return an iterator providing access to the text and its attributes     */    public AttributedCharacterIterator getIterator(Attribute[] attributes) {        return getIterator(attributes, 0, length());    }    /**     * Creates an AttributedCharacterIterator instance that provides access to     * selected contents of this string.     * Information about attributes not listed in attributes that the     * implementor may have need not be made accessible through the iterator.     * If the list is null, all available attribute information should be made     * accessible.     *     * @param attributes a list of attributes that the client is interested in     * @param beginIndex the index of the first character     * @param endIndex the index of the character following the last character     * @return an iterator providing access to the text and its attributes     * @exception IllegalArgumentException if beginIndex is less then 0,     * endIndex is greater than the length of the string, or beginIndex is     * greater than endIndex.     */    public AttributedCharacterIterator getIterator(Attribute[] attributes, int beginIndex, int endIndex) {        return new AttributedStringIterator(attributes, beginIndex, endIndex);    }    // all (with the exception of length) reading operations are private,    // since AttributedString instances are accessed through iterators.    // length is package private so that CharacterIteratorFieldDelegate can    // access it without creating an AttributedCharacterIterator.    int length() {        return text.length();    }        private char charAt(int index) {        return text.charAt(index);    }        private synchronized Object getAttribute(Attribute attribute, int runIndex) {        Vector currentRunAttributes = runAttributes[runIndex];        Vector currentRunAttributeValues = runAttributeValues[runIndex];        if (currentRunAttributes == null) {            return null;        }        int attributeIndex = currentRunAttributes.indexOf(attribute);        if (attributeIndex != -1) {            return currentRunAttributeValues.elementAt(attributeIndex);        }        else {            return null;        }    }    // gets an attribute value, but returns an annotation only if it's range does not extend outside the range beginIndex..endIndex    private Object getAttributeCheckRange(Attribute attribute, int runIndex, int beginIndex, int endIndex) {        Object value = getAttribute(attribute, runIndex);        if (value instanceof Annotation) {            // need to check whether the annotation's range extends outside the iterator's range            if (beginIndex > 0) {                int currIndex = runIndex;                int runStart = runStarts[currIndex];                while (runStart >= beginIndex &&                        valuesMatch(value, getAttribute(attribute, currIndex - 1))) {                    currIndex--;                    runStart = runStarts[currIndex];                }                if (runStart < beginIndex) {                    // annotation's range starts before iterator's range                    return null;                }            }            int textLength = length();            if (endIndex < textLength) {                int currIndex = runIndex;                int runLimit = (currIndex < runCount - 1) ? runStarts[currIndex + 1] : textLength;                while (runLimit <= endIndex &&                        valuesMatch(value, getAttribute(attribute, currIndex + 1))) {                    currIndex++;                    runLimit = (currIndex < runCount - 1) ? runStarts[currIndex + 1] : textLength;                }                if (runLimit > endIndex) {                    // annotation's range ends after iterator's range                    return null;                }            }            // annotation's range is subrange of iterator's range,            // so we can return the value        }        return value;    }    // returns whether all specified attributes have equal values in the runs with the given indices    private boolean attributeValuesMatch(Set attributes, int runIndex1, int runIndex2) {        Iterator iterator = attributes.iterator();        while (iterator.hasNext()) {            Attribute key = (Attribute) iterator.next();           if (!valuesMatch(getAttribute(key, runIndex1), getAttribute(key, runIndex2))) {                return false;            }        }        return true;    }    // returns whether the two objects are either both null or equal    private final static boolean valuesMatch(Object value1, Object value2) {        if (value1 == null) {            return value2 == null;        } else {            return value1.equals(value2);        }    }    /**     * Appends the contents of the CharacterIterator iterator into the     * StringBuffer buf.     */    private final void appendContents(StringBuffer buf,                                      CharacterIterator iterator) {        int index = iterator.getBeginIndex();        int end = iterator.getEndIndex();        while (index < end) {            iterator.setIndex(index++);            buf.append(iterator.current());        }    }    /**     * Sets the attributes for the range from offset to the the next run break      * (typically the end of the text) to the ones specified in attrs.     * This is only meant to be called from the constructor!     */    private void setAttributes(Map attrs, int offset) {        if (runCount == 0) {            createRunAttributeDataVectors();        }        int index = ensureRunBreak(offset, false);        int size;        if (attrs != null && (size = attrs.size()) > 0) {            Vector runAttrs = new Vector(size);            Vector runValues = new Vector(size);            Iterator iterator = attrs.entrySet().iterator();            while (iterator.hasNext()) {                Map.Entry entry = (Map.Entry)iterator.next();                runAttrs.add(entry.getKey());                runValues.add(entry.getValue());            }            runAttributes[index] = runAttrs;            runAttributeValues[index] = runValues;	            }    }    /**     * Returns true if the attributes specified in last and attrs differ.     */    private static boolean mapsDiffer(Map last, Map attrs) {        if (last == null) {            return (attrs != null && attrs.size() > 0);        }        return (!last.equals(attrs));    }    // the iterator class associated with this string class    final private class AttributedStringIterator implements AttributedCharacterIterator {                // note on synchronization:        // we don't synchronize on the iterator, assuming that an iterator is only used in one thread.        // we do synchronize access to the AttributedString however, since it's more likely to be shared between threads.        // start and end index for our iteration        private int beginIndex;        private int endIndex;                // attributes that our client is interested in        private Attribute[] relevantAttributes;        // the current index for our iteration        // invariant: beginIndex <= currentIndex <= endIndex        private int currentIndex;        // information about the run that includes currentIndex        private int currentRunIndex;        private int currentRunStart;        private int currentRunLimit;                // constructor        AttributedStringIterator(Attribute[] attributes, int beginIndex, int endIndex) {                    if (beginIndex < 0 || beginIndex > endIndex || endIndex > length()) {                throw new IllegalArgumentException("Invalid substring range");            }                        this.beginIndex = beginIndex;            this.endIndex = endIndex;            this.currentIndex = beginIndex;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -