Blackberry ListField Text Wrapping - всего две строки - PullRequest
1 голос
/ 02 февраля 2010

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

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 были правильно смещены, и эторисовал текст только после того, как ширина строки превысила ширину экрана, а также оставшуюся строку после нее), однако каждый раз, когда я пытаюсь получить первые две строки, он всегда заканчивается возвращением последних двух строк строки, если она идетза две линии.Есть ли лучший способ сделать что-то подобное, так как я только что из идей?

Ответы [ 2 ]

2 голосов
/ 03 февраля 2010

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

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 голосов
/ 09 мая 2010

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

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;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...