/** Returns previous character */ private int getPrevious() { char c2 = text.previous(); if (Character.isLowSurrogate(c2) && text.getIndex() > text.getBeginIndex()) { char c1 = text.previous(); if (Character.isHighSurrogate(c1)) { return Character.toCodePoint(c1, c2); } else { text.next(); } } return (int) c2; }
/** * Returns true if the specified position is a boundary position. As a side effect, leaves the * iterator pointing to the first boundary position at or after "offset". * * @param offset the offset to check. * @return True if "offset" is a boundary position. */ @Override public boolean isBoundary(int offset) { CharacterIterator text = getText(); checkOffset(offset, text); if (offset == text.getBeginIndex()) { return true; } // to check whether this is a boundary, we can use following() on the // position before the specified one and return true if the position we // get back is the one the user specified else { return following(offset - 1) == offset; } }
public void selectionDone(SelectionEvent evt) { if (!useUnixTextSelection) return; Object o = evt.getSelection(); if (!(o instanceof CharacterIterator)) return; CharacterIterator iter = (CharacterIterator) o; // first see if we can access the clipboard SecurityManager securityManager; securityManager = System.getSecurityManager(); if (securityManager != null) { try { securityManager.checkSystemClipboardAccess(); } catch (SecurityException e) { return; // Can't access clipboard. } } int sz = iter.getEndIndex() - iter.getBeginIndex(); if (sz == 0) return; char[] cbuff = new char[sz]; cbuff[0] = iter.first(); for (int i = 1; i < cbuff.length; ++i) { cbuff[i] = iter.next(); } final String strSel = new String(cbuff); // HACK: getSystemClipboard sometimes deadlocks on // linux when called from the AWT Thread. The Thread // creation prevents that. new Thread() { public void run() { Clipboard cb; cb = Toolkit.getDefaultToolkit().getSystemClipboard(); StringSelection sel; sel = new StringSelection(strSel); cb.setContents(sel, sel); } }.start(); }
/** * Advances the iterator backwards, to the last boundary preceding this one. * * @return The position of the last boundary position preceding this one. */ @Override public int previous() { // if we're already sitting at the beginning of the text, return DONE CharacterIterator text = getText(); if (current() == text.getBeginIndex()) { return BreakIterator.DONE; } // set things up. handlePrevious() will back us up to some valid // break position before the current position (we back our internal // iterator up one step to prevent handlePrevious() from returning // the current position), but not necessarily the last one before // where we started int start = current(); int lastResult = cachedLastKnownBreak; if (lastResult >= start || lastResult <= BreakIterator.DONE) { getPrevious(); lastResult = handlePrevious(); } else { // it might be better to check if handlePrevious() give us closer // safe value but handlePrevious() is slow too // So, this has to be done carefully text.setIndex(lastResult); } int result = lastResult; // iterate forward from the known break position until we pass our // starting point. The last break position before the starting // point is our return value while (result != BreakIterator.DONE && result < start) { lastResult = result; result = handleNext(); } // set the current iteration position to be the last break position // before where we started, and then return that value text.setIndex(lastResult); cachedLastKnownBreak = lastResult; return lastResult; }
/** * Sets the iterator to refer to the first boundary position following the specified position. * * @offset The position from which to begin searching for a break position. * @return The position of the first break after the current position. */ @Override public int following(int offset) { CharacterIterator text = getText(); checkOffset(offset, text); // Set our internal iteration position (temporarily) // to the position passed in. If this is the _beginning_ position, // then we can just use next() to get our return value text.setIndex(offset); if (offset == text.getBeginIndex()) { cachedLastKnownBreak = handleNext(); return cachedLastKnownBreak; } // otherwise, we have to sync up first. Use handlePrevious() to back // us up to a known break position before the specified position (if // we can determine that the specified position is a break position, // we don't back up at all). This may or may not be the last break // position at or before our starting position. Advance forward // from here until we've passed the starting position. The position // we stop on will be the first break position after the specified one. int result = cachedLastKnownBreak; if (result >= offset || result <= BreakIterator.DONE) { result = handlePrevious(); } else { // it might be better to check if handlePrevious() give us closer // safe value but handlePrevious() is slow too // So, this has to be done carefully text.setIndex(result); } while (result != BreakIterator.DONE && result <= offset) { result = handleNext(); } cachedLastKnownBreak = result; return result; }
public int getBeginIndex() { return iterator.getBeginIndex(); }
public int getLength() { return (iterator.getEndIndex() - iterator.getBeginIndex()); }
/** Throw IllegalArgumentException unless begin <= offset < end. */ protected static final void checkOffset(int offset, CharacterIterator text) { if (offset < text.getBeginIndex() || offset > text.getEndIndex()) { throw new IllegalArgumentException("offset out of bounds"); } }
SafeCharIterator(CharacterIterator base) { this.base = base; this.rangeStart = base.getBeginIndex(); this.rangeLimit = base.getEndIndex(); this.currentIndex = base.getIndex(); }