下面是我自己的答案,寻找灵感:
public final class TextWrapper {
enum Strategy implements WrapStrategy {
HARD {
@Override
public String wrap(final Iterable<String> words, final int width) {
return Joiner.on('\n')
.join(Splitter
.fixedLength(width)
.split(
Joiner.on(' ').join(words)));
}
},
SOFT {
@Override
public String wrap(final Iterable<String> words, final int width) {
final StringBuilder sb = new StringBuilder();
int lineLength = 0;
final Iterator<String> iterator = words.iterator();
if (iterator.hasNext()) {
sb.append(iterator.next());
lineLength=sb.length();
while (iterator.hasNext()) {
final String word = iterator.next();
if(word.length()+1+lineLength>width) {
sb.append('\n');
lineLength=0;
} else {
lineLength++;
sb.append(' ');
}
sb.append(word);
lineLength+=word.length();
}
}
return sb.toString();
}
}
}
interface WrapStrategy {
String wrap(Iterable<String> words, int width);
}
public static TextWrapper forWidth(final int i) {
return new TextWrapper(Strategy.SOFT, CharMatcher.WHITESPACE, i);
}
private final WrapStrategy strategy;
private final CharMatcher delimiter;
private final int width;
TextWrapper(final WrapStrategy strategy,
final CharMatcher delimiter, final int width) {
this.strategy = strategy;
this.delimiter = delimiter;
this.width = width;
}
public TextWrapper hard(){
return new TextWrapper(Strategy.HARD, this.delimiter, this.width);
}
public TextWrapper respectExistingBreaks() {
return new TextWrapper(
this.strategy, CharMatcher.anyOf(" \t"), this.width);
}
public String wrap(final String text) {
return this.strategy.wrap(
Splitter.on(this.delimiter).split(text), this.width);
}
}
用法示例1:(80个字符硬包装)
TextWrapper.forWidth(80)
.hard()
.wrap("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
"Maecenas porttitor risus vitae urna hendrerit ac condimentum " +
"odio tincidunt.\nDonec porttitor felis quis nulla aliquet " +
"lobortis. Suspendisse mattis sapien ut metus congue tincidunt. " +
"Quisque gravida, augue sed congue tempor, tortor augue rhoncus " +
"leo, eget luctus nisl risus id erat. Nunc tempor pretium gravida.");
输出:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas porttitor risu
s vitae urna hendrerit ac condimentum odio tincidunt. Donec porttitor felis quis
nulla aliquet lobortis. Suspendisse mattis sapien ut metus congue tincidunt. Qu
isque gravida, augue sed congue tempor, tortor augue rhoncus leo, eget luctus ni
sl risus id erat. Nunc tempor pretium gravida.
用法示例2:(在或或前60个字符软包装,保留现有换行符)
TextWrapper.forWidth(60)
.respectExistingBreaks()
.wrap("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n" +
"Maecenas porttitor risus vitae urna hendrerit ac condimentum " +
"odio tincidunt.\nDonec porttitor felis quis nulla aliquet " +
"lobortis. Suspendisse mattis sapien ut metus congue tincidunt. " +
"Quisque gravida, augue sed congue tempor, tortor augue rhoncus " +
"leo, eget luctus nisl risus id erat. Nunc tempor pretium gravida.");
输出:
Lorem ipsum dolor sit amet, consectetur adipiscing
elit.
Maecenas porttitor risus vitae urna hendrerit ac
condimentum odio tincidunt.
Donec porttitor felis quis nulla
aliquet lobortis. Suspendisse mattis sapien ut metus congue
tincidunt. Quisque gravida, augue sed congue tempor, tortor
augue rhoncus leo, eget luctus nisl risus id erat. Nunc
tempor pretium gravida.
我通常有两个库,并使用一个时,其他没有我想要的确切功能。 – Bozho 2011-04-14 11:00:34
@Bozho我也是,但从长远来看,我只想用番石榴替代commons/lang和commons/io。而这个功能目前是交易停止者之一。 – 2011-04-14 11:02:21
只是好奇;你为什么要做自己的文字布局? – 2011-04-16 20:09:57