下一行时自定义编辑字段错误

时间:2012-07-03 09:28:00

标签: blackberry blackberry-editfield

我正在尝试输入字符来填充编辑字段,如果文本仍然在第一行我没有问题,但是当第一行已满时它会转到下一行,我收到以下错误:

0:01:56.609: Uncaught: StackOverflowError

这是我的custom_editfield:

public class Custom_EditField extends EditField {

int width, row;

Custom_EditField(long style, int width, int row) {
    super(style);
    this.width = width;
    this.row = row;
}

public int getPreferredHeight() {
    return Font.getDefault().getHeight() * row;
}

public int getPreferredWidth() {
    return width;
}

protected void layout(int maxWidth, int maxHeight) {
    super.layout(maxWidth,
            Math.min(maxHeight, Font.getDefault().getHeight() * row));
    super.setExtent(maxWidth,
            Math.min(maxHeight, Font.getDefault().getHeight() * row));
}

/*public int drawText(Graphics graphics, int offset, int length, int x,
        int y, DrawTextParam drawTextParam) {
    graphics.setBackgroundColor(Color.GRAY);
    graphics.clear();
    graphics.setColor(Color.BLACK);
    int labelWidth = getFont().getAdvance(getLabel());
    graphics.drawRect(labelWidth, 0, getWidth() - labelWidth, getHeight());
    return graphics.drawText(
            this.getText().substring(offset, offset + length), x, y);
}*/

protected void paint(Graphics graphics) {
    int rectHeight = getPreferredHeight();
    int rectWidth = getPreferredWidth();
    graphics.setBackgroundColor(Color.GRAY);
    graphics.clear();
    graphics.setColor(Color.BLACK);
    graphics.drawRect(0, 0, rectWidth, rectHeight);
    super.paint(graphics);
}
}

我还注意到光标是透明的。你认为光标会导致这个问题吗?

这是我打电话给编辑区

extends VerticalFIeldManager

protected void sublayout(int width, int height) {

    comments = new Custom_EditField(Field.FIELD_HCENTER
            | Field.FIELD_VCENTER | Field.FOCUSABLE,
            getPreferredWidth() - 10, 3);
    add(comments);

    namelabel = new Custom_LabelField("姓名:", DrawStyle.ELLIPSIS
            | LabelField.USE_ALL_WIDTH | DrawStyle.LEFT | Field.FIELD_LEFT);
    namelabel.setFont(Font.getDefault().derive(Font.BOLD, 20));
    namelabel.setFontColor(Color.BLACK);
    add(namelabel);

    postbtn = new ButtonField("留言", DrawStyle.HCENTER | Field.FIELD_RIGHT);
    postbtn.setPadding(0, 20, 0, 20);
    postbtn.setChangeListener(this);
    add(postbtn);

    name = new Custom_EditField(Field.FIELD_HCENTER | Field.FIELD_VCENTER
            | Field.FOCUSABLE, getPreferredWidth()
            - namelabel.getPreferredWidth() - postbtn.getContentWidth() - 5
            * 4, 1);
    add(name);

    Field field = getField(0);
    layoutChild(field, getPreferredWidth() - 10,
            comments.getPreferredHeight());
    setPositionChild(field, 5, 5);

    field = getField(1);
    layoutChild(field, Font.getDefault().getAdvance(namelabel.getText()),
            namelabel.getContentHeight());
    setPositionChild(field, 5, comments.getPreferredHeight() + 5 * 2);

    field = getField(2);
    layoutChild(field, postbtn.getPreferredWidth() + postbtn.getWidth(),
            name.getPreferredHeight());
    setPositionChild(field, getPreferredWidth() - (postbtn.getWidth() + 5),
            comments.getPreferredHeight() + 5 * 2);

    field = getField(3);
    layoutChild(field, getPreferredWidth() * 2 / 3,
            name.getPreferredHeight());
    setPositionChild(field, namelabel.getWidth(),
            comments.getPreferredHeight() + 5 * 2);

    width = Math.min(width, getPreferredWidth());
    height = Math.min(height, getPreferredHeight());
    setExtent(width, height);
}

1 个答案:

答案 0 :(得分:0)

解决方案

我仍然无法构建您的代码,因为发布的Manager代码使用了您未展示的类Custom_LabelField。但是,我认为Custom_LabelField有点像LabelField。如果我将name指定为LabelField,那么我会看到您的StackOverflowError。

正如@EugenMartynov所说,您正在sublayout()的实现中设置标签字段的文本。这实际上会导致sublayout()从内部再次被调用。这会导致再次创建namelabel,并且该过程将无限重复,直到堆栈耗尽。

实际上,sublayout()方法只能用于布局操作:定位和大小调整。在此之前,您通常应该创建您的Field个对象。通常,这发生在构造函数中。如果将sublayout方法的前半部分移动到构造函数,则可以解决此问题:

public class MyManager extends VerticalFieldManager {
   public MyManager() {
      super(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);

      comments = new Custom_EditField(Field.FIELD_HCENTER 
        | Field.FIELD_VCENTER | Field.FOCUSABLE, 
        getPreferredWidth() - 10, 3); 
      add(comments); 

      namelabel = new Custom_LabelField("姓名:", DrawStyle.ELLIPSIS 
        | LabelField.USE_ALL_WIDTH | DrawStyle.LEFT | Field.FIELD_LEFT); 
      namelabel.setFont(Font.getDefault().derive(Font.BOLD, 20)); 
      namelabel.setFontColor(Color.BLACK); 
      add(namelabel); 

      postbtn = new ButtonField("留言", DrawStyle.HCENTER | Field.FIELD_RIGHT); 
      postbtn.setPadding(0, 20, 0, 20); 
      postbtn.setChangeListener(this); 
      add(postbtn); 

      name = new Custom_EditField(Field.FIELD_HCENTER | Field.FIELD_VCENTER 
        | Field.FOCUSABLE, getPreferredWidth() 
        - namelabel.getPreferredWidth() - postbtn.getContentWidth() - 5 
        * 4, 1); 
      add(name); 
   }
}

然后sublayout()变得更简单:

protected void sublayout(int height, int width) {
   Field field = getField(0);    
   layoutChild(field, getPreferredWidth() - 10,    
        comments.getPreferredHeight());    
   setPositionChild(field, 5, 5);    

   field = getField(1);    
   layoutChild(field, Font.getDefault().getAdvance(namelabel.getText()),    
        namelabel.getContentHeight());    
   setPositionChild(field, 5, comments.getPreferredHeight() + 5 * 2);    

   field = getField(2);    
   layoutChild(field, postbtn.getPreferredWidth() + postbtn.getWidth(),    
        name.getPreferredHeight());    
   setPositionChild(field, getPreferredWidth() - (postbtn.getWidth() + 5),    
        comments.getPreferredHeight() + 5 * 2);    

   field = getField(3);    
   layoutChild(field, getPreferredWidth() * 2 / 3,    
        name.getPreferredHeight());    
   setPositionChild(field, namelabel.getWidth(),    
        comments.getPreferredHeight() + 5 * 2);    

   width = Math.min(width, getPreferredWidth());    
   height = Math.min(height, getPreferredHeight());    
   setExtent(width, height);    
}

一般资料

如果您想知道如何捕获StackOverflowError,请将此代码放在顶级UiApplication子类中(仅用于调试...在发布应用程序之前删除它):

  try {
     MyApp theApp = new MyApp();       
     theApp.enterEventDispatcher();
  } catch (Throwable e) {
     e.printStackTrace();
  }

点击e.printStackTrace()后,您的Eclipse 控制台窗口将显示如下内容:

[375.664]  0x16 
[375.664] HelloBlackBerry(4FF4123E) 
[375.664]  MyManager 
[375.664]  sublayout 
[375.664]  0x16 
[375.664] HelloBlackBerry(4FF4123E) 
[375.664]  MyManager 
[375.664]  sublayout 
[375.664]  0x16 
[375.664] HelloBlackBerry(4FF4123E) 
[375.664]  MyManager 
[375.664]  sublayout 
[375.664]  0x16 
[375.664] HelloBlackBerry(4FF4123E) 
[375.664]  MyManager 
[375.664]  sublayout 
[375.664]  0x16 
[375.664] HelloBlackBerry(4FF4123E)

您可以一遍又一遍地看到几乎完全相同的时间戳(375.664),正在调用sublayout类中的MyManager方法。当你看到它时,你知道你需要查看那个方法,因为它正在调用它自己。