2009-07-13 10 views
2

Il existe mille articles sur la façon d'utiliser LineBreakMeasurer pour dessiner du texte multiligne, mais il n'y en a pas sur le dessin de texte multiligne en tenant compte également de \ n (lorsque vous voulez forcer une nouvelle ligne à un position dans le texte et pas seulement lorsque la marge de droite ou de gauche se termine).Gestion n dans LineBreakMeasurer

Le secret semble se situer dans BreakIterator, mais je n'ai pas trouvé d'implémentation qui gère \ n.

Répondre

2

Marquez d'abord le texte, puis appliquez le LineBreakMeasureCode à chaque token.

+1

Ceci est une possibilité, mais je voudrais une solution qui utilise uniquement LineBreakerMeasurer. –

2

Au lieu de LineBreakMeasurer (LBM) méthode nextLayout(float), utilisez la méthode surchargée LBM.nextLayout(float, int, boolean). Cela vous permet de limiter le texte que LBM inclura dans le TextLayout retourné. Dans votre cas, vous lui ordonnerez de ne pas aller au-delà du prochain saut de ligne.

Cet extrait de code devrait vous donner l'idée. D'abord, utilisez LBM.nextOffset pour "jeter un coup d'oeil" sur l'index de caractères qui sera la fin de la mise en page suivante. Puis passez en revue votre contenu de chaîne jusqu'à ce décalage pour voir si vous trouvez des caractères de nouvelle ligne. Si vous le faites, utilisez cette limite trouvé que le second argument de nextLayout(float, int, boolean) qui dira LBM ne pas dépasser la nouvelle ligne:

int next = lineMeasurer.nextOffset(formatWidth); 
int limit = next; 
if (limit < totalLength) { 
    for (int i = lineMeasurer.getPosition(); i < next; ++i) { 
     char c = string.charAt(i); 
     if (c == '\n') { 
     limit = i; 
     break; 
     } 
    } 
} 

TextLayout layout = lineMeasurer.nextLayout(formatWidth, limit, false); 

Références

http://java.sun.com/developer/onlineTraining/Media/2DText/style.html#layout http: //java.sun. com/developer/onlineTraining/Media/2DText/Code/LineBreakSample.java

+0

Un couple de problèmes avec ce code, alors j'ai posté une version qui fonctionne pour moi ci-dessous. –

1

Je trouve que ce code fonctionne bien pour le problème de nouvelle ligne. J'ai utilisé atdixon comme modèle pour l'obtenir.

while (measurer.getPosition() < paragraph.getEndIndex()) { 
    next = measurer.nextOffset(wrappingWidth); 
    limit = next; 
    charat = tested.indexOf('\n',measurer.getPosition()+1); 
    if(next > (charat - measurer.getPosition()) && charat != -1){ 
     limit = charat - measurer.getPosition(); 
    } 
    layout = measurer.nextLayout(wrappingWidth, measurer.getPosition()+limit, false); 
    // Do the rest of your layout and pen work. 
} 
1

code d'Aaron ne fonctionne pas toujours est vrai alors voici un code pincé qui fonctionne pour moi:

int next = measurer.nextOffset(width); 
int limit = next; 
if (limit <= text.length()) { 
    for (int i = measurer.getPosition(); i < next; ++i) { 
    char c = text.charAt(i); 
    if (c == '\n') { 
     limit = i + 1; 
     break; 
    } 
    } 
} 
TextLayout textLayout = measurer.nextLayout(width, limit, false); 

Si vous avez besoin du texte à partir d'un vous AttributedString pouvez simplement le faire à l'avance

AttributedCharacterIterator iterator = attributedString.getIterator(); 
StringBuilder stringBuilder = new StringBuilder(iterator.getEndIndex()); 
while (iterator.getIndex() < iterator.getEndIndex()) { 
    stringBuilder.append(iterator.current()); 
    iterator.next(); 
} 
String text = stringBuilder.toString();