1

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

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

1 回答 1

0

解决方案

我仍然无法构建您的代码,因为Manager发布的代码使用了Custom_LabelField您尚未显示的 class 。但是,我认为这Custom_LabelField有点像LabelField. 如果我指定name为 a 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当您看到它时,您知道您需要查看该方法,因为它正在调用自己。

于 2012-07-04T10:09:54.417 回答