下面列出了java.text.BreakIterator#last ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Vector testLastAndPrevious(BreakIterator bi, String text) {
int p = bi.last();
int lastP = p;
Vector<String> result = new Vector<String>();
if (p != text.length())
errln("last() returned " + p + " instead of " + text.length());
while (p != BreakIterator.DONE) {
p = bi.previous();
if (p != BreakIterator.DONE) {
if (p >= lastP)
errln("previous() failed to move backward: previous() on position "
+ lastP + " yielded " + p);
result.insertElementAt(text.substring(p, lastP), 0);
}
else {
if (lastP != 0)
errln("previous() returned DONE prematurely: offset was "
+ lastP + " instead of 0");
}
lastP = p;
}
return result;
}
private Vector testLastAndPrevious(BreakIterator bi, String text) {
int p = bi.last();
int lastP = p;
Vector<String> result = new Vector<String>();
if (p != text.length())
errln("last() returned " + p + " instead of " + text.length());
while (p != BreakIterator.DONE) {
p = bi.previous();
if (p != BreakIterator.DONE) {
if (p >= lastP)
errln("previous() failed to move backward: previous() on position "
+ lastP + " yielded " + p);
result.insertElementAt(text.substring(p, lastP), 0);
}
else {
if (lastP != 0)
errln("previous() returned DONE prematurely: offset was "
+ lastP + " instead of 0");
}
lastP = p;
}
return result;
}
private Vector testLastAndPrevious(BreakIterator bi, String text) {
int p = bi.last();
int lastP = p;
Vector<String> result = new Vector<String>();
if (p != text.length())
errln("last() returned " + p + " instead of " + text.length());
while (p != BreakIterator.DONE) {
p = bi.previous();
if (p != BreakIterator.DONE) {
if (p >= lastP)
errln("previous() failed to move backward: previous() on position "
+ lastP + " yielded " + p);
result.insertElementAt(text.substring(p, lastP), 0);
}
else {
if (lastP != 0)
errln("previous() returned DONE prematurely: offset was "
+ lastP + " instead of 0");
}
lastP = p;
}
return result;
}
private Vector testLastAndPrevious(BreakIterator bi, String text) {
int p = bi.last();
int lastP = p;
Vector<String> result = new Vector<String>();
if (p != text.length())
errln("last() returned " + p + " instead of " + text.length());
while (p != BreakIterator.DONE) {
p = bi.previous();
if (p != BreakIterator.DONE) {
if (p >= lastP)
errln("previous() failed to move backward: previous() on position "
+ lastP + " yielded " + p);
result.insertElementAt(text.substring(p, lastP), 0);
}
else {
if (lastP != 0)
errln("previous() returned DONE prematurely: offset was "
+ lastP + " instead of 0");
}
lastP = p;
}
return result;
}
private void doMultipleSelectionTest(BreakIterator iterator, String testText)
{
logln("Multiple selection test...");
BreakIterator testIterator = (BreakIterator)iterator.clone();
int offset = iterator.first();
int testOffset;
int count = 0;
do {
testOffset = testIterator.first();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count++;
offset = iterator.next();
}
} while (offset != BreakIterator.DONE);
// now do it backwards...
offset = iterator.last();
count = 0;
do {
testOffset = testIterator.last();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count--;
offset = iterator.previous();
}
} while (offset != BreakIterator.DONE);
}
private void doMultipleSelectionTest(BreakIterator iterator, String testText)
{
logln("Multiple selection test...");
BreakIterator testIterator = (BreakIterator)iterator.clone();
int offset = iterator.first();
int testOffset;
int count = 0;
do {
testOffset = testIterator.first();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count++;
offset = iterator.next();
}
} while (offset != BreakIterator.DONE);
// now do it backwards...
offset = iterator.last();
count = 0;
do {
testOffset = testIterator.last();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count--;
offset = iterator.previous();
}
} while (offset != BreakIterator.DONE);
}
/**
* set / update the text of the displayLabels. these are the Week column
* headers above the days on the Calendar part of the <code>CDateTime</code>
* .
*/
private void updateDaysOfWeek() {
if (dayPanel != null) {
Calendar tmpcal = cdt.getCalendarInstance();
tmpcal.set(Calendar.DAY_OF_WEEK, tmpcal.getFirstDayOfWeek());
Locale locale = cdt.getLocale();
boolean ltr = ComponentOrientation.getOrientation(locale)
.isLeftToRight() && !locale.getLanguage().equals("zh"); //$NON-NLS-1$
BreakIterator iterator = BreakIterator.getCharacterInstance(locale);
for (VLabel dayLabel : dayLabels) {
String str = getFormattedDate("E", tmpcal.getTime()); //$NON-NLS-1$
if (dayLabel.getData(CDT.Key.Compact, Boolean.class)) {
iterator.setText(str);
int start, end;
if (ltr) {
start = iterator.first();
end = iterator.next();
} else {
end = iterator.last();
start = iterator.previous();
}
dayLabel.setText(str.substring(start, end));
} else {
dayLabel.setText(str);
}
tmpcal.add(Calendar.DAY_OF_WEEK, 1);
}
}
}
private void doMultipleSelectionTest(BreakIterator iterator, String testText)
{
logln("Multiple selection test...");
BreakIterator testIterator = (BreakIterator)iterator.clone();
int offset = iterator.first();
int testOffset;
int count = 0;
do {
testOffset = testIterator.first();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count++;
offset = iterator.next();
}
} while (offset != BreakIterator.DONE);
// now do it backwards...
offset = iterator.last();
count = 0;
do {
testOffset = testIterator.last();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count--;
offset = iterator.previous();
}
} while (offset != BreakIterator.DONE);
}
private void doMultipleSelectionTest(BreakIterator iterator, String testText)
{
logln("Multiple selection test...");
BreakIterator testIterator = (BreakIterator)iterator.clone();
int offset = iterator.first();
int testOffset;
int count = 0;
do {
testOffset = testIterator.first();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count++;
offset = iterator.next();
}
} while (offset != BreakIterator.DONE);
// now do it backwards...
offset = iterator.last();
count = 0;
do {
testOffset = testIterator.last();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count--;
offset = iterator.previous();
}
} while (offset != BreakIterator.DONE);
}
private void testFirstAndLast(BreakIterator bi, String text, String boundaries) {
String message = "Text: " + text;
int current = bi.current();
assertEquals(message, boundaries.indexOf('^'), current);
assertEquals(message, current, bi.first());
assertEquals(message, current, bi.current());
current = bi.last();
assertEquals(boundaries.lastIndexOf('^'), current);
assertEquals(message, current, bi.current());
}
private void testPrevious(BreakIterator bi, String text, String boundaries) {
String message = "Text: " + text;
bi.setText(text);
int idx = bi.last();//position at the end
while (true) {
idx = boundaries.lastIndexOf('^', idx - 1);
if (idx == -1) {
assertEquals(message, BreakIterator.DONE, bi.previous());
break;
}
assertEquals(message, idx, bi.previous());
}
assertEquals(message, boundaries.indexOf('^'), bi.current());//finishes at first
}
private static void fillBreaks(@NonNull String text, @NonNull byte[] breaks, byte type) {
BreakIterator iterator;
switch (type) {
case CHARACTER:
iterator = BreakIterator.getCharacterInstance();
break;
default:
iterator = BreakIterator.getLineInstance();
break;
}
iterator.setText(text);
iterator.first();
byte forwardType = typeMode(type, true);
int charNext;
while ((charNext = iterator.next()) != BreakIterator.DONE) {
breaks[charNext - 1] |= forwardType;
}
iterator.last();
byte backwardType = typeMode(type, false);
int charIndex;
while ((charIndex = iterator.previous()) != BreakIterator.DONE) {
breaks[charIndex] |= backwardType;
}
}
private void doMultipleSelectionTest(BreakIterator iterator, String testText)
{
logln("Multiple selection test...");
BreakIterator testIterator = (BreakIterator)iterator.clone();
int offset = iterator.first();
int testOffset;
int count = 0;
do {
testOffset = testIterator.first();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count++;
offset = iterator.next();
}
} while (offset != BreakIterator.DONE);
// now do it backwards...
offset = iterator.last();
count = 0;
do {
testOffset = testIterator.last();
testOffset = testIterator.next(count);
logln("next(" + count + ") -> " + testOffset);
if (offset != testOffset)
errln("next(n) and next() not returning consistent results: for step " + count + ", next(n) returned " + testOffset + " and next() had " + offset);
if (offset != BreakIterator.DONE) {
count--;
offset = iterator.previous();
}
} while (offset != BreakIterator.DONE);
}
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;
}
/**
* 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 <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();
}
/**
* 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();
}
/** Asserts that two breakiterators break the text the same way */
public static void assertSameBreaks(CharacterIterator one, CharacterIterator two, BreakIterator expected, BreakIterator actual) {
expected.setText(one);
actual.setText(two);
assertEquals(expected.current(), actual.current());
// next()
int v = expected.current();
while (v != BreakIterator.DONE) {
assertEquals(v = expected.next(), actual.next());
assertEquals(expected.current(), actual.current());
}
// first()
assertEquals(expected.first(), actual.first());
assertEquals(expected.current(), actual.current());
// last()
assertEquals(expected.last(), actual.last());
assertEquals(expected.current(), actual.current());
// previous()
v = expected.current();
while (v != BreakIterator.DONE) {
assertEquals(v = expected.previous(), actual.previous());
assertEquals(expected.current(), actual.current());
}
// following()
for (int i = one.getBeginIndex(); i <= one.getEndIndex(); i++) {
expected.first();
actual.first();
assertEquals(expected.following(i), actual.following(i));
assertEquals(expected.current(), actual.current());
}
// preceding()
for (int i = one.getBeginIndex(); i <= one.getEndIndex(); i++) {
expected.last();
actual.last();
assertEquals(expected.preceding(i), actual.preceding(i));
assertEquals(expected.current(), actual.current());
}
}
/**
* 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();
}