2010-02-02 4 views
1

В моем ListField я хочу иметь возможность взять любую заданную длинную строку и просто иметь возможность обернуть первую строку в ширину экрана и просто взять оставшуюся строку и отобразите его ниже и эллипсис остальное. Прямо сейчас, это то, что я использую, чтобы обнаружить обертывание в моем розыгрыше краски вызова:Blackberry ListField Text Wrapping - только две строки

int totalWidth = 0; 
int charWidth = 0; 
int lastIndex = 0; 
int spaceIndex = 0; 
int lineIndex = 0; 
String firstLine = ""; 
String secondLine = ""; 
boolean isSecondLine = false; 

for (int i = 0; i < longString.length(); i++){ 
    charWidth = Font.getDefault().getAdvance(String.valueOf(longString.charAt(i))); 
    //System.out.println("char width: " + charWidth); 
    if(longString.charAt(i) == ' ') 
    spaceIndex = i; 
    if((charWidth + totalWidth) > (this.getWidth()-32)){ 
      //g.drawText(longString.substring(lastIndex, spaceIndex), xpos, y +_padding, DrawStyle.LEFT, w - xpos); 
      lineIndex++; 
    System.out.println("current lines to draw: " + lineIndex); 
    /*if (lineIndex = 2){ 
    int idx = i; 
    System.out.println("first line " + longString.substring(lastIndex, spaceIndex)); 
    System.out.println("second line " + longString.substring(spaceIndex+1, longString.length())); 
    }*/ 
    //firstLine = longString.substring(lastIndex, spaceIndex); 
    firstLine = longString.substring(0, spaceIndex); 
    //System.out.println("first new line: " +firstLine); 
    //isSecondLine=true; 
    //xpos = 0; 
    //y += Font.getDefault().getHeight(); 
    i = spaceIndex + 1; 
    lastIndex = i; 
    System.out.println("Rest of string: " + longString.substring(lastIndex, longString.length())); 

    charWidth = 0; 
    totalWidth = 0; 
    } 
    totalWidth += charWidth; 
    System.out.println("total width: " + totalWidth); 
    //g.drawText(longString.substring(lastIndex, i+1), xpos, y + (_padding*3)+4, DrawStyle.ELLIPSIS, w - xpos); 

    //secondLine = longString.substring(lastIndex, i+1); 
    secondLine = longString.substring(lastIndex, longString.length()); 
    //isSecondLine = true; 
} 

Теперь это большая работа на самом деле оборачивать любую заданную строку (при условии Y значения были правильно offsetted и только обратил текст после ширины строки превысил ширину экрана, а также оставшуюся строку), однако каждый раз, когда я пытаюсь получить первые две строки, он всегда заканчивает возвращение двух последних строк строки, если он выходит за рамки двух линий. Есть ли лучший способ сделать такие вещи, так как я свеж от идей?

ответ

2

Я не совсем уверен, что понимаю, что вы вопрос, но это звучит для меня так же, как вам нужен алгоритм обертывания слов, который сдается после двух строк. Если это так, то это, надеюсь, заставит вас указывать в правильном направлении.

void wrapString(String inputString, int width, Font font){ 
    String line1; 
    String line2; 

    if (font.getAdvance(inputString) <= width){ 
     line1 = inputString; 
     line2 = ""; 
    } 
    else{ 
     int charsInLine1 = countCharsInLine(inputString, 0, inputString.length()-1, width, font); 
     int lineBreak = inputString.lastIndexOf(' ', charsInLine1); 
     if (lineBreak == -1) 
      lineBreak = charsInLine1; 
     line1 = inputString.substring(0, lineBreak); 

     line2 = inputString.substring(lineBreak+1, inputString.length()); 
     if (font.getAdvance(line2) > width){ 
      int charsInLine2 = countCharsInLine(line2, 0, inputString.length()-1, width - font.getAdvance("..."), font); 
      line2 = line2.substring(0, charsInLine2) + "..."; 
     } 
    } 

    System.out.println("line1: " + line1); 
    System.out.println("line2: " + line2); 
} 

int countCharsInLine(String str, int min, int max, int width, Font font) { 

    if (min >= max) 
     return max; 

    int guess = min + (max - min)/2; 
    int advance = font.getAdvance(str, 0, guess); 

    if (advance < width) 
     return countCharsInLine(str, guess+1, max, width, font); 
    else if (advance > width) 
     return countCharsInLine(str, min, guess-1, width, font); 
    else 
     return guess; 
} 
+0

Спасибо за помощь, пока он действительно работает, когда ему не нужно выполнять проверку пересылки второй строки, так как после попытки компенсировать ширину многоточия, она ломается, пытаясь угадать длину символа. Тем не менее, я смог адаптировать этот же алгоритм с вызовами drawText в отдельной функции и позволить эллипсису второй линии от вызова краски. Пока что спасибо за помощь, хотя я хотел бы знать, можете ли вы вернуться к расчету догадок только для пинков. –

0

Я сделал что-то подобное, но он вернет все извращенные линии. Вы можете использовать первый элемент возвращенного вектора и совместить отдых элементы, чтобы получить две строки, которые вы хотите:

private Vector wrap (String text, int width) 
{ 
    Vector result = new Vector(); 

    String remaining = text; 


    while (remaining.length()>=0) 
    { 
     int index = getSplitIndex(remaining, width); 

     if (index == -1) 
      break; 

     result.addElement(remaining.substring(0,index)); 

     remaining = remaining.substring(index); 

     if (index == 0) 
      break; 
    } 

    return result; 
} 


private int getSplitIndex(String bigString, int width) 
{ 
    int index = -1; 
    int lastSpace = -1; 
    String smallString=""; 
    boolean spaceEncountered = false; 
    boolean maxWidthFound = false; 

    for (int i=0; i<bigString.length(); i++) 
    { 
     char current = bigString.charAt(i); 
     smallString += current; 


     if (current == ' ') 
     { 
      lastSpace = i; 
      spaceEncountered = true; 
     } 

     int linewidth = this.getFont().getAdvance(smallString,0, smallString.length()); 

     if(linewidth>width) 
     { 
      if (spaceEncountered) 
       index = lastSpace+1; 
      else 
       index = i; 

      maxWidthFound = true; 

      break; 


     } 


    } 

    if (!maxWidthFound) 
     index = bigString.length(); 


    return index; 
} 

Am еще тестируем и не работает нормально до сих пор.