【问题标题】:Blackberry ListField Text Wrapping - only two lines黑莓 ListField 文本换行 - 只有两行
【发布时间】:2019-04-16 07:08:51
【问题描述】:

在我的 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 值被正确偏移,并​​且它只在字符串宽度超过屏幕宽度之后绘制文本,以及之后的剩余字符串),但是,每个当我尝试获取前两行时,如果超过两行,它总是最终返回字符串的最后两行。有没有更好的方法来做这种事情,因为我刚刚没有想法?

【问题讨论】:

    标签: java blackberry


    【解决方案1】:

    我不完全确定我是否理解您的问题,但在我看来,您需要一个自动换行算法,该算法在两行之后就放弃了。如果是这样的话,那么这应该可以让你找到正确的方向。

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

    【讨论】:

    • 感谢您的帮助,到目前为止,当它不必进行第二行字体提前检查时,它实际上可以工作,因为在尝试补偿省略号宽度后,它会在尝试猜测时中断字符长度。但是,我能够在一个单独的函数中使用 drawText 调用来调整相同的算法,并让第二行省略来自 paint 调用。到目前为止,感谢您的帮助,尽管我想知道您是否可以重新考虑一下猜测计算。
    【解决方案2】:

    我做过类似的事情,但它会返回所有扭曲的线条。然后,您可以使用返回向量的第一个元素并组合其余元素以获得您想要的两行:

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

    到目前为止,我仍在测试和工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多