如何证明Blackberry中的LabelField

时间:2013-03-02 11:59:25

标签: blackberry

我的文字内容很长,我希望使用LabelField或其他内容在justify alignment屏幕上显示。目前,我可以执行右/左/中心对齐但不能对齐对齐。

是否有任何自定义控件可以帮助我这样做?

1 个答案:

答案 0 :(得分:2)

这只是一个原型,因此可能会有一些它无法处理的事情。但是,它应该是一个开始,你可以用来做你想要的。大多数重要逻辑都在paint()方法中。

我不知道有任何内置(RIM库)方法。

public class JustifiedLabelField extends LabelField {

   /** a cache of the label's words, to avoid having to recalculate every
       time paint() is called */
   private String[] _words;
   /** the dynamic field height */
   private int _height = 0;

   public JustifiedLabelField(Object text, long style){
      super(text, style);
      setText(text);
   }

   public void setText(Object text) {
      // update the words cache when text changes
      _words = split((String)text, " ");  // NOTE: this only supports String type!
      super.setText(text);
   }

   public int getPreferredHeight() {
      // I believe overriding this method is necessary because the 
      //  justification might produce a different total number of lines, 
      //  depending on the algorithm used
      return (_height > 0) ? _height : super.getPreferredHeight();
   }

   protected void paint(Graphics g) {
      Font font = g.getFont();
      int space = font.getAdvance(' ');
      int fontHeight = font.getHeight();
      int fieldWidth = getWidth();         
      int word = 0;
      int y = 0;
      while (word < _words.length) {
         // each iteration of this loop handles one line
         int wordsInLine = 0;
         int lineWordWidths = 0;
         // first loop over all words that fit on this line, to measure
         while (word < _words.length) {
            int wordWidth = font.getAdvance(_words[word]);
            if (lineWordWidths + wordWidth <= fieldWidth) {
               lineWordWidths += (wordWidth + space);
               word++;
               wordsInLine++;
            } else {
               break;
            }
         }

         // how much total space (gap) should be placed between every two words?
         int gapSpacing = 0;
         if (word == _words.length) {
            // don't justify at all on last line
            gapSpacing = space;
         } else if (wordsInLine != 1) {
            gapSpacing = (fieldWidth - (lineWordWidths - wordsInLine * space)) / (wordsInLine - 1);
         }

         int x = 0;
         // now actually draw the words, with added spacing
         for (int j = word - wordsInLine; j < word; j++) {
            int span = g.drawText(_words[j], x, y);
            x += span + gapSpacing;            
         }

         y += fontHeight;
      }
      _height = y;
   }
}

上述代码使用String split()方法。您可以找到one possible implementation here

然后,使用这样的类:

   public LabelScreen() {
      super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

      String loremIpsum = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam cursus. Morbi ut mi. Nullam enim leo, egestas id, condimentum at, laoreet mattis, massa. Sed eleifend nonummy diam. Praesent mauris ante, elementum et, bibendum at, posuere sit amet, nibh. Duis tincidunt lectus quis dui viverra vestibulum. Suspendisse vulputate aliquam dui. Nulla elementum dui ut augue. Aliquam vehicula mi at mauris. Maecenas placerat, nisl at consequat rhoncus, sem nunc gravida justo, quis eleifend arcu velit quis lacus. Morbi magna magna, tincidunt a, mattis non, imperdiet vitae, tellus. Sed odio est, auctor ac, sollicitudin in, consequat vitae, orci. Fusce id felis. Vivamus sollicitudin metus eget eros.";
      JustifiedLabelField label = new JustifiedLabelField(loremIpsum, Field.NON_FOCUSABLE);
      add(label);
   }

产生这个:

enter image description here

限制

  • 我没有做任何事情来解释这个领域的填充
  • LabelField允许您使用其他类型调用setText()或构造函数,而不只是String。我的班级只支持String,但您可以轻松扩展它。
  • 我的班级仅在空格(' ')上拆分字符串。您可能希望支持拆分其他字符,甚至插入破折号来打破很长的单词。我会留给你的。
  • 我没有测试任何边缘情况,就像长度超过字段宽度的单词一样。我只用全屏宽度字段测试了这个,中小字。
  • 请参阅Eugen对the page I link to使用的split()方法
  • 的评论

后续

我对上面发布的代码进行了细化,然后发布了online here。较新的版本应该处理填充,这个版本没有。如果你选择一个字符串拆分算法来改变LabelField超类认为该字段应该有多少行,它也应该处理垂直大小问题。更多评论。