下面列出了java.text.BreakIterator#following ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Needed to unify forward and backward searching.
* The method assumes that s is the text assigned to words.
*/
private int findWordLimit(int index, BreakIterator words, boolean direction,
String s) {
// Fix for 4256660 and 4256661.
// Words iterator is different from character and sentence iterators
// in that end of one word is not necessarily start of another word.
// Please see java.text.BreakIterator JavaDoc. The code below is
// based on nextWordStartAfter example from BreakIterator.java.
int last = (direction == NEXT) ? words.following(index)
: words.preceding(index);
int current = (direction == NEXT) ? words.next()
: words.previous();
while (current != BreakIterator.DONE) {
for (int p = Math.min(last, current); p < Math.max(last, current); p++) {
if (Character.isLetter(s.charAt(p))) {
return last;
}
}
last = current;
current = (direction == NEXT) ? words.next()
: words.previous();
}
return BreakIterator.DONE;
}
/**
* Needed to unify forward and backward searching.
* The method assumes that s is the text assigned to words.
*/
private int findWordLimit(int index, BreakIterator words, boolean direction,
String s) {
// Fix for 4256660 and 4256661.
// Words iterator is different from character and sentence iterators
// in that end of one word is not necessarily start of another word.
// Please see java.text.BreakIterator JavaDoc. The code below is
// based on nextWordStartAfter example from BreakIterator.java.
int last = (direction == NEXT) ? words.following(index)
: words.preceding(index);
int current = (direction == NEXT) ? words.next()
: words.previous();
while (current != BreakIterator.DONE) {
for (int p = Math.min(last, current); p < Math.max(last, current); p++) {
if (Character.isLetter(s.charAt(p))) {
return last;
}
}
last = current;
current = (direction == NEXT) ? words.next()
: words.previous();
}
return BreakIterator.DONE;
}
private void testFollowing(BreakIterator bi, String text, int[] boundaries) {
logln("testFollowing():");
int p = 2;
int i = 0;
try {
for (i = 0; i <= text.length(); i++) { // change to <= when new BI code goes in
if (i == boundaries[p])
++p;
int b = bi.following(i);
logln("bi.following(" + i + ") -> " + b);
if (b != boundaries[p])
errln("Wrong result from following() for " + i + ": expected " + boundaries[p]
+ ", got " + b);
}
} catch (IllegalArgumentException illargExp) {
errln("IllegalArgumentException caught from following() for offset: " + i);
}
}
/**
* Needed to unify forward and backward searching.
* The method assumes that s is the text assigned to words.
*/
private int findWordLimit(int index, BreakIterator words, boolean direction,
String s) {
// Fix for 4256660 and 4256661.
// Words iterator is different from character and sentence iterators
// in that end of one word is not necessarily start of another word.
// Please see java.text.BreakIterator JavaDoc. The code below is
// based on nextWordStartAfter example from BreakIterator.java.
int last = (direction == NEXT) ? words.following(index)
: words.preceding(index);
int current = (direction == NEXT) ? words.next()
: words.previous();
while (current != BreakIterator.DONE) {
for (int p = Math.min(last, current); p < Math.max(last, current); p++) {
if (Character.isLetter(s.charAt(p))) {
return last;
}
}
last = current;
current = (direction == NEXT) ? words.next()
: words.previous();
}
return BreakIterator.DONE;
}
/**
* Needed to unify forward and backward searching.
* The method assumes that s is the text assigned to words.
*/
private int findWordLimit(int index, BreakIterator words, boolean direction,
String s) {
// Fix for 4256660 and 4256661.
// Words iterator is different from character and sentence iterators
// in that end of one word is not necessarily start of another word.
// Please see java.text.BreakIterator JavaDoc. The code below is
// based on nextWordStartAfter example from BreakIterator.java.
int last = (direction == NEXT) ? words.following(index)
: words.preceding(index);
int current = (direction == NEXT) ? words.next()
: words.previous();
while (current != BreakIterator.DONE) {
for (int p = Math.min(last, current); p < Math.max(last, current); p++) {
if (Character.isLetter(s.charAt(p))) {
return last;
}
}
last = current;
current = (direction == NEXT) ? words.next()
: words.previous();
}
return BreakIterator.DONE;
}
private void testFollowing(BreakIterator bi, String text, int[] boundaries) {
logln("testFollowing():");
int p = 2;
int i = 0;
try {
for (i = 0; i <= text.length(); i++) { // change to <= when new BI code goes in
if (i == boundaries[p])
++p;
int b = bi.following(i);
logln("bi.following(" + i + ") -> " + b);
if (b != boundaries[p])
errln("Wrong result from following() for " + i + ": expected " + boundaries[p]
+ ", got " + b);
}
} catch (IllegalArgumentException illargExp) {
errln("IllegalArgumentException caught from following() for offset: " + i);
}
}
/**
* Needed to unify forward and backward searching.
* The method assumes that s is the text assigned to words.
*/
private int findWordLimit(int index, BreakIterator words, boolean direction,
String s) {
// Fix for 4256660 and 4256661.
// Words iterator is different from character and sentence iterators
// in that end of one word is not necessarily start of another word.
// Please see java.text.BreakIterator JavaDoc. The code below is
// based on nextWordStartAfter example from BreakIterator.java.
int last = (direction == NEXT) ? words.following(index)
: words.preceding(index);
int current = (direction == NEXT) ? words.next()
: words.previous();
while (current != BreakIterator.DONE) {
for (int p = Math.min(last, current); p < Math.max(last, current); p++) {
if (Character.isLetter(s.charAt(p))) {
return last;
}
}
last = current;
current = (direction == NEXT) ? words.next()
: words.previous();
}
return BreakIterator.DONE;
}
/**
* Returns the Segment at <code>index</code> representing either
* the paragraph or sentence as identified by <code>part</code>, or
* null if a valid paragraph/sentence can't be found. The offset
* will point to the start of the word/sentence in the array, and
* the modelOffset will point to the location of the word/sentence
* in the model.
*/
private IndexedSegment getSegmentAt(int part, int index)
throws BadLocationException {
IndexedSegment seg = getParagraphElementText(index);
if (seg == null) {
return null;
}
BreakIterator iterator;
switch (part) {
case AccessibleText.WORD:
iterator = BreakIterator.getWordInstance(getLocale());
break;
case AccessibleText.SENTENCE:
iterator = BreakIterator.getSentenceInstance(getLocale());
break;
default:
return null;
}
seg.first();
iterator.setText(seg);
int end = iterator.following(index - seg.modelOffset + seg.offset);
if (end == BreakIterator.DONE) {
return null;
}
if (end > seg.offset + seg.count) {
return null;
}
int begin = iterator.previous();
if (begin == BreakIterator.DONE ||
begin >= seg.offset + seg.count) {
return null;
}
seg.modelOffset = seg.modelOffset + begin - seg.offset;
seg.offset = begin;
seg.count = end - begin;
return seg;
}
/** Assumes that {@code getArea().getLength != 0} is true and {@link BreakIterator#setText(String)} has been called */
private int calculatePositionViaBreakingForwards(int numOfBreaks, BreakIterator breakIterator, int position) {
breakIterator.following(position);
for (int i = 1; i < numOfBreaks; i++) {
breakIterator.next(numOfBreaks);
}
return breakIterator.current();
}
/**
* Returns the Segment at <code>index</code> representing either
* the paragraph or sentence as identified by <code>part</code>, or
* null if a valid paragraph/sentence can't be found. The offset
* will point to the start of the word/sentence in the array, and
* the modelOffset will point to the location of the word/sentence
* in the model.
*/
private IndexedSegment getSegmentAt(int part, int index)
throws BadLocationException {
IndexedSegment seg = getParagraphElementText(index);
if (seg == null) {
return null;
}
BreakIterator iterator;
switch (part) {
case AccessibleText.WORD:
iterator = BreakIterator.getWordInstance(getLocale());
break;
case AccessibleText.SENTENCE:
iterator = BreakIterator.getSentenceInstance(getLocale());
break;
default:
return null;
}
seg.first();
iterator.setText(seg);
int end = iterator.following(index - seg.modelOffset + seg.offset);
if (end == BreakIterator.DONE) {
return null;
}
if (end > seg.offset + seg.count) {
return null;
}
int begin = iterator.previous();
if (begin == BreakIterator.DONE ||
begin >= seg.offset + seg.count) {
return null;
}
seg.modelOffset = seg.modelOffset + begin - seg.offset;
seg.offset = begin;
seg.count = end - begin;
return seg;
}
public static int getWordStart(JTextComponent c, int offs) throws BadLocationException {
Element line = Optional.ofNullable(Utilities.getParagraphElement(c, offs))
.orElseThrow(() -> new BadLocationException("No word at " + offs, offs));
Document doc = c.getDocument();
int lineStart = line.getStartOffset();
int lineEnd = Math.min(line.getEndOffset(), doc.getLength());
int offs2 = offs;
Segment seg = SegmentCache.getSharedSegment();
doc.getText(lineStart, lineEnd - lineStart, seg);
if (seg.count > 0) {
BreakIterator words = BreakIterator.getWordInstance(c.getLocale());
words.setText(seg);
int wordPosition = seg.offset + offs - lineStart;
if (wordPosition >= words.last()) {
wordPosition = words.last() - 1;
words.following(wordPosition);
offs2 = lineStart + words.previous() - seg.offset;
} else {
words.following(wordPosition);
offs2 = lineStart + words.previous() - seg.offset;
for (int i = offs; i > offs2; i--) {
char ch = seg.charAt(i - seg.offset);
if (ch == '_' || ch == '-') {
offs2 = i + 1;
break;
}
}
}
}
SegmentCache.releaseSharedSegment(seg);
return offs2;
}
public static int getWordEnd(JTextComponent c, int offs) throws BadLocationException {
Element line = Optional.ofNullable(Utilities.getParagraphElement(c, offs))
.orElseThrow(() -> new BadLocationException("No word at " + offs, offs));
Document doc = c.getDocument();
int lineStart = line.getStartOffset();
int lineEnd = Math.min(line.getEndOffset(), doc.getLength());
int offs2 = offs;
Segment seg = SegmentCache.getSharedSegment();
doc.getText(lineStart, lineEnd - lineStart, seg);
if (seg.count > 0) {
BreakIterator words = BreakIterator.getWordInstance(c.getLocale());
words.setText(seg);
int wordPosition = offs - lineStart + seg.offset;
if (wordPosition >= words.last()) {
wordPosition = words.last() - 1;
}
offs2 = lineStart + words.following(wordPosition) - seg.offset;
for (int i = offs; i < offs2; i++) {
char ch = seg.charAt(i - seg.offset);
if (ch == '_' || ch == '-') {
offs2 = i;
break;
}
}
}
SegmentCache.releaseSharedSegment(seg);
return offs2;
}
/**
* Tries to find the word at the given offset.
*
* @param line
* the line
* @param offset
* the offset
* @return the word or <code>null</code> if none
*/
protected static IRegion findWordRegion(String line, int offset)
{
BreakIterator breakIter = BreakIterator.getWordInstance();
breakIter.setText(line);
int start = breakIter.preceding(offset);
if (start == BreakIterator.DONE)
start = 0;
int end = breakIter.following(offset);
if (end == BreakIterator.DONE)
end = line.length();
if (breakIter.isBoundary(offset))
{
if (end - offset > offset - start)
{
start = offset;
}
else
{
end = offset;
}
}
if (end == start)
{
return new Region(start, 0);
}
return new Region(start, end - start);
}
/**
* Returns the Segment at <code>index</code> representing either
* the paragraph or sentence as identified by <code>part</code>, or
* null if a valid paragraph/sentence can't be found. The offset
* will point to the start of the word/sentence in the array, and
* the modelOffset will point to the location of the word/sentence
* in the model.
*/
private IndexedSegment getSegmentAt(int part, int index)
throws BadLocationException {
IndexedSegment seg = getParagraphElementText(index);
if (seg == null) {
return null;
}
BreakIterator iterator;
switch (part) {
case AccessibleText.WORD:
iterator = BreakIterator.getWordInstance(getLocale());
break;
case AccessibleText.SENTENCE:
iterator = BreakIterator.getSentenceInstance(getLocale());
break;
default:
return null;
}
seg.first();
iterator.setText(seg);
int end = iterator.following(index - seg.modelOffset + seg.offset);
if (end == BreakIterator.DONE) {
return null;
}
if (end > seg.offset + seg.count) {
return null;
}
int begin = iterator.previous();
if (begin == BreakIterator.DONE ||
begin >= seg.offset + seg.count) {
return null;
}
seg.modelOffset = seg.modelOffset + begin - seg.offset;
seg.offset = begin;
seg.count = end - begin;
return seg;
}
private void testFollowing(BreakIterator bi, String text, String boundaries, List<Integer> indexes) {
String message = "Text: " + text;
for (Integer index : indexes) {
int got = bi.following(index);
if (index == boundaries.length()) {
assertEquals(message, BreakIterator.DONE, got);
assertEquals(boundaries.lastIndexOf('^'), bi.current());
continue;
}
assertEquals(message + " index:" + index, boundaries.indexOf('^', index + 1), got);
}
}
/**
* Returns the Segment at <code>index</code> representing either
* the paragraph or sentence as identified by <code>part</code>, or
* null if a valid paragraph/sentence can't be found. The offset
* will point to the start of the word/sentence in the array, and
* the modelOffset will point to the location of the word/sentence
* in the model.
*/
private IndexedSegment getSegmentAt(int part, int index)
throws BadLocationException {
IndexedSegment seg = getParagraphElementText(index);
if (seg == null) {
return null;
}
BreakIterator iterator;
switch (part) {
case AccessibleText.WORD:
iterator = BreakIterator.getWordInstance(getLocale());
break;
case AccessibleText.SENTENCE:
iterator = BreakIterator.getSentenceInstance(getLocale());
break;
default:
return null;
}
seg.first();
iterator.setText(seg);
int end = iterator.following(index - seg.modelOffset + seg.offset);
if (end == BreakIterator.DONE) {
return null;
}
if (end > seg.offset + seg.count) {
return null;
}
int begin = iterator.previous();
if (begin == BreakIterator.DONE ||
begin >= seg.offset + seg.count) {
return null;
}
seg.modelOffset = seg.modelOffset + begin - seg.offset;
seg.offset = begin;
seg.count = end - begin;
return seg;
}
@Override
protected IRegion findWord(IDocument document, int offset) {
try {
IRegion line = document.getLineInformationOfOffset(offset);
if (offset == line.getOffset() + line.getLength())
return null;
BreakIterator breakIter = createBreakIterator();
CharacterIterator characterIterator = new DocumentCharacterIterator(document);
breakIter.setText(characterIterator);
int start = breakIter.preceding(offset);
if (start == BreakIterator.DONE)
start = line.getOffset();
int end = breakIter.following(offset);
if (end == BreakIterator.DONE)
end = line.getOffset() + line.getLength();
if (breakIter.isBoundary(offset)) {
if (end - offset > offset - start)
start = offset;
else
end = offset;
}
if (end == start)
return null;
return new Region(start, end - start);
} catch (BadLocationException e) {
return null;
}
}
@Override // to select words containing underscores
public void selectWord()
{
if ( getLength() == 0 ) return;
CaretSelectionBind<?,?,?> csb = getCaretSelectionBind();
int paragraph = csb.getParagraphIndex();
int position = csb.getColumnPosition();
String paragraphText = getText( paragraph );
BreakIterator breakIterator = BreakIterator.getWordInstance( getLocale() );
breakIterator.setText( paragraphText );
breakIterator.preceding( position );
int start = breakIterator.current();
while ( start > 0 && paragraphText.charAt( start-1 ) == '_' )
{
if ( --start > 0 && ! breakIterator.isBoundary( start-1 ) )
{
breakIterator.preceding( start );
start = breakIterator.current();
}
}
breakIterator.following( position );
int end = breakIterator.current();
int len = paragraphText.length();
while ( end < len && paragraphText.charAt( end ) == '_' )
{
if ( ++end < len && ! breakIterator.isBoundary( end+1 ) )
{
breakIterator.following( end );
end = breakIterator.current();
}
// For some reason single digits aren't picked up so ....
else if ( Character.isDigit( paragraphText.charAt( end ) ) )
{
end++;
}
}
csb.selectRange( paragraph, start, paragraph, end );
}
/**
* Returns the character index of the next line break. If the next
* character is wider than <code>width</code> this method will return
* <code>start</code> - the caller should check for this case.
*
* @param text the text (<code>null</code> not permitted).
* @param start the start index.
* @param width the target display width.
* @param iterator the word break iterator.
* @param measurer the text measurer.
*
* @return The index of the next line break.
*/
private static int nextLineBreak(String text, int start, float width,
BreakIterator iterator, TextMeasurer measurer) {
// this method is (loosely) based on code in JFreeReport's
// TextParagraph class
int current = start;
int end;
float x = 0.0f;
boolean firstWord = true;
int newline = text.indexOf('\n', start);
if (newline < 0) {
newline = Integer.MAX_VALUE;
}
while (((end = iterator.following(current)) != BreakIterator.DONE)) {
x += measurer.getStringWidth(text, current, end);
if (x > width) {
if (firstWord) {
while (measurer.getStringWidth(text, start, end) > width) {
end--;
if (end <= start) {
return end;
}
}
return end;
}
else {
end = iterator.previous();
return end;
}
}
else {
if (end > newline) {
return newline;
}
}
// we found at least one word that fits ...
firstWord = false;
current = end;
}
return BreakIterator.DONE;
}
private int getNextWordBoundary(CharSequence text, int selectionEnd) {
BreakIterator boundary = BreakIterator.getWordInstance();
boundary.setText(text.toString());
int next = boundary.following(selectionEnd);
return (next == BreakIterator.DONE) ? selectionEnd : next;
}