下面列出了java.text.BreakIterator#preceding ( ) 实例代码,或者点击链接到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;
}
/**
* 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;
}
/**
* 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;
}
/**
* 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;
}
/**
* 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;
}
/**
* 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;
}
/**
* 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);
}
@Override
public boolean onDoubleTap(MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
// find the position
int offset = getOffsetForPosition(x, y);
// select word
BreakIterator iterator = BreakIterator.getWordInstance();
iterator.setText(getText().toString());
// start and end are the word boundaries;
int start;
if (iterator.isBoundary(offset)) {
start = offset;
} else {
start = iterator.preceding(offset);
}
int end = iterator.following(offset);
// handle tapping at the very beginning or end.
if (end == BreakIterator.DONE) {
end = start;
start = iterator.preceding(offset);
if (start == BreakIterator.DONE) start = end;
}
setSelection(start, end);
return super.onDoubleTap(e);
}
/**
* Returns a location to break at in the passed in region, or
* BreakIterator.DONE if there isn't a good location to break at
* in the specified region.
*/
private int getBreakSpot(int p0, int p1) {
if (breakSpots == null) {
// Re-calculate breakpoints for the whole view
int start = getStartOffset();
int end = getEndOffset();
int[] bs = new int[end + 1 - start];
int ix = 0;
// Breaker should work on the parent element because there may be
// a valid breakpoint at the end edge of the view (space, etc.)
Element parent = getElement().getParentElement();
int pstart = (parent == null ? start : parent.getStartOffset());
int pend = (parent == null ? end : parent.getEndOffset());
Segment s = getText(pstart, pend);
s.first();
BreakIterator breaker = getBreaker();
breaker.setText(s);
// Backward search should start from end+1 unless there's NO end+1
int startFrom = end + (pend > end ? 1 : 0);
for (;;) {
startFrom = breaker.preceding(s.offset + (startFrom - pstart))
+ (pstart - s.offset);
if (startFrom > start) {
// The break spot is within the view
bs[ix++] = startFrom;
} else {
break;
}
}
SegmentCache.releaseSharedSegment(s);
breakSpots = new int[ix];
System.arraycopy(bs, 0, breakSpots, 0, ix);
}
int breakSpot = BreakIterator.DONE;
for (int i = 0; i < breakSpots.length; i++) {
int bsp = breakSpots[i];
if (bsp <= p1) {
if (bsp > p0) {
breakSpot = bsp;
}
break;
}
}
return breakSpot;
}
/**
* Method converts single-line string to the word-wrapped multiline string with the given max-width
* and max-line-number values (if the string is longer than that - the rest of the string will
* be thrown out and "..." will be added to the end)
*
* @param input - the source string
* @param width - the max width of one line of text
* @param maxlines - the max number of lines that result string can contain
* @param locale - the source string locale; is used to determine the possible places to make word-wraps in the source string
* @return the string with word wrapping
*/
public static String wordWrap(String input, int width, int maxlines, Locale locale) {
if (input == null) {
return "";
}
if (width >= input.length()) {
return input;
}
StringBuilder buf = new StringBuilder(input);
boolean endOfLine = false;
int lineStart = 0;
for (int i = 0; i < buf.length(); i++) {
if (buf.charAt(i) == '\n') {
lineStart = i + 1;
endOfLine = true;
}
// handle splitting at width character
if (i > lineStart + width - 1) {
if (!endOfLine) {
int limit = i - lineStart - 1;
BreakIterator breaks = BreakIterator.getLineInstance(locale);
breaks.setText(buf.substring(lineStart, i));
int end = breaks.last();
// if the last character in the search string isn't a space,
// we can't split on it. Search for a previous break character
if (end == limit + 1) {
if (!Character.isWhitespace(buf.charAt(lineStart + end))) {
end = breaks.preceding(end - 1);
}
}
// if the last character is a space - replace it with \n
if (end != BreakIterator.DONE && end == limit + 1) {
buf.replace(lineStart + end, lineStart + end + 1, "\n");
lineStart = lineStart + end;
}
// otherwise - just insert a \n
else if (end != BreakIterator.DONE && end != 0) {
buf.insert(lineStart + end, '\n');
lineStart = lineStart + end + 1;
}
else {
buf.insert(i, '\n');
lineStart = i + 1;
}
}
else {
buf.insert(i, '\n');
lineStart = i + 1;
endOfLine = false;
}
}
}
// Throw out excess strings
String result = buf.toString();
StringBuilder builder = new StringBuilder();
String[] lines = result.split("\n");
if (lines != null && lines.length > maxlines) {
String shortedStr = "...";
if (lines[maxlines - 1].length() + shortedStr.length() <= width) {
lines[maxlines - 1] = lines[maxlines - 1] + shortedStr;
} else {
lines[maxlines - 1] = lines[maxlines -1].substring(0, width - shortedStr.length()) + shortedStr;
}
for (int i = 0; i < maxlines; i++) {
builder.append(lines[i]).append("\n");
}
result = builder.toString();
result = result.substring(0, result.length() - 1);
}
return result;
}
/**
* Reformats a string where lines that are longer than {@code width}
* are split apart at the earliest wordbreak or at maxLength, whichever is
* sooner. If the width specified is less than 5 or greater than the input
* Strings length the string will be returned as is.
* <p>
* Please note that this method can be lossy - trailing spaces on wrapped
* lines may be trimmed.</p>
*
* @param input the String to reformat.
* @param width the maximum length of any one line.
* @param locale the local
* @return a new String with reformatted as needed.
*/
public static String wordWrap(String input, int width, Locale locale) {
// protect ourselves
if (input == null) {
return "";
}
else if (width < 5) {
return input;
}
else if (width >= input.length()) {
return input;
}
// default locale
if (locale == null) {
locale = JiveGlobals.getLocale();
}
StringBuilder buf = new StringBuilder(input);
boolean endOfLine = false;
int lineStart = 0;
for (int i = 0; i < buf.length(); i++) {
if (buf.charAt(i) == '\n') {
lineStart = i + 1;
endOfLine = true;
}
// handle splitting at width character
if (i > lineStart + width - 1) {
if (!endOfLine) {
int limit = i - lineStart - 1;
BreakIterator breaks = BreakIterator.getLineInstance(locale);
breaks.setText(buf.substring(lineStart, i));
int end = breaks.last();
// if the last character in the search string isn't a space,
// we can't split on it (looks bad). Search for a previous
// break character
if (end == limit + 1) {
if (!Character.isWhitespace(buf.charAt(lineStart + end))) {
end = breaks.preceding(end - 1);
}
}
// if the last character is a space, replace it with a \n
if (end != BreakIterator.DONE && end == limit + 1) {
buf.replace(lineStart + end, lineStart + end + 1, "\n");
lineStart = lineStart + end;
}
// otherwise, just insert a \n
else if (end != BreakIterator.DONE && end != 0) {
buf.insert(lineStart + end, '\n');
lineStart = lineStart + end + 1;
}
else {
buf.insert(i, '\n');
lineStart = i + 1;
}
}
else {
buf.insert(i, '\n');
lineStart = i + 1;
endOfLine = false;
}
}
}
return buf.toString();
}
/**
* Returns a location to break at in the passed in region, or
* BreakIterator.DONE if there isn't a good location to break at
* in the specified region.
*/
private int getBreakSpot(int p0, int p1) {
if (breakSpots == null) {
// Re-calculate breakpoints for the whole view
int start = getStartOffset();
int end = getEndOffset();
int[] bs = new int[end + 1 - start];
int ix = 0;
// Breaker should work on the parent element because there may be
// a valid breakpoint at the end edge of the view (space, etc.)
Element parent = getElement().getParentElement();
int pstart = (parent == null ? start : parent.getStartOffset());
int pend = (parent == null ? end : parent.getEndOffset());
Segment s = getText(pstart, pend);
s.first();
BreakIterator breaker = getBreaker();
breaker.setText(s);
// Backward search should start from end+1 unless there's NO end+1
int startFrom = end + (pend > end ? 1 : 0);
for (;;) {
startFrom = breaker.preceding(s.offset + (startFrom - pstart))
+ (pstart - s.offset);
if (startFrom > start) {
// The break spot is within the view
bs[ix++] = startFrom;
} else {
break;
}
}
SegmentCache.releaseSharedSegment(s);
breakSpots = new int[ix];
System.arraycopy(bs, 0, breakSpots, 0, ix);
}
int breakSpot = BreakIterator.DONE;
for (int i = 0; i < breakSpots.length; i++) {
int bsp = breakSpots[i];
if (bsp <= p1) {
if (bsp > p0) {
breakSpot = bsp;
}
break;
}
}
return breakSpot;
}
/**
* Reformats a string where lines that are longer than <tt>width</tt>
* <p/>
* are split apart at the earliest wordbreak or at maxLength, whichever is
* <p/>
* sooner. If the width specified is less than 5 or greater than the input
* <p/>
* Strings length the string will be returned as is.
* <p/>
* <p/>
* <p/>
* Please note that this method can be lossy - trailing spaces on wrapped
* <p/>
* lines may be trimmed.
*
* @param input
* the String to reformat.
* @param width
* the maximum length of any one line.
* @param locale
* of the string to be wrapped.
* @return a new String with reformatted as needed.
*/
public static String wordWrap(String input, int width, Locale locale) {
// protect ourselves
if (input == null) {
return "";
} else if (width < 5) {
return input;
} else if (width >= input.length()) {
return input;
}
StringBuilder buf = new StringBuilder(input);
boolean endOfLine = false;
int lineStart = 0;
for (int i = 0; i < buf.length(); i++) {
if (buf.charAt(i) == '\n') {
lineStart = i + 1;
endOfLine = true;
}
// handle splitting at width character
if (i > lineStart + width - 1) {
if (!endOfLine) {
int limit = i - lineStart - 1;
BreakIterator breaks = BreakIterator
.getLineInstance(locale);
breaks.setText(buf.substring(lineStart, i));
int end = breaks.last();
// if the last character in the search string isn't a space,
// we can't split on it (looks bad). Search for a previous
// break character
if (end == limit + 1) {
if (!Character
.isWhitespace(buf.charAt(lineStart + end))) {
end = breaks.preceding(end - 1);
}
}
// if the last character is a space, replace it with a \n
if (end != BreakIterator.DONE && end == limit + 1) {
buf.replace(lineStart + end, lineStart + end + 1, "\n");
lineStart = lineStart + end;
}
// otherwise, just insert a \n
else if (end != BreakIterator.DONE && end != 0) {
buf.insert(lineStart + end, '\n');
lineStart = lineStart + end + 1;
} else {
buf.insert(i, '\n');
lineStart = i + 1;
}
} else {
buf.insert(i, '\n');
lineStart = i + 1;
endOfLine = false;
}
}
}
return buf.toString();
}
/**
* Returns a location to break at in the passed in region, or
* BreakIterator.DONE if there isn't a good location to break at
* in the specified region.
*/
private int getBreakSpot(int p0, int p1) {
if (breakSpots == null) {
// Re-calculate breakpoints for the whole view
int start = getStartOffset();
int end = getEndOffset();
int[] bs = new int[end + 1 - start];
int ix = 0;
// Breaker should work on the parent element because there may be
// a valid breakpoint at the end edge of the view (space, etc.)
Element parent = getElement().getParentElement();
int pstart = (parent == null ? start : parent.getStartOffset());
int pend = (parent == null ? end : parent.getEndOffset());
Segment s = getText(pstart, pend);
s.first();
BreakIterator breaker = getBreaker();
breaker.setText(s);
// Backward search should start from end+1 unless there's NO end+1
int startFrom = end + (pend > end ? 1 : 0);
for (;;) {
startFrom = breaker.preceding(s.offset + (startFrom - pstart))
+ (pstart - s.offset);
if (startFrom > start) {
// The break spot is within the view
bs[ix++] = startFrom;
} else {
break;
}
}
SegmentCache.releaseSharedSegment(s);
breakSpots = new int[ix];
System.arraycopy(bs, 0, breakSpots, 0, ix);
}
int breakSpot = BreakIterator.DONE;
for (int i = 0; i < breakSpots.length; i++) {
int bsp = breakSpots[i];
if (bsp <= p1) {
if (bsp > p0) {
breakSpot = bsp;
}
break;
}
}
return breakSpot;
}