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。しかし、それCustom_LabelFieldはやや。のようなものだと思いLabelFieldます。に割り当てるnameLabelField、StackOverflowErrorが表示されます。

@EugenMartynovが言ったように、の実装内にラベルフィールドのテキストを設定していますsublayout()。これにより、実際にはsublayout()、それ自体の内部から再度呼び出されます。これによりnamelabel、再度作成され、スタックが使い果たされるまでプロセスが無限に繰り返されます。

実際、この方法は、レイアウト操作(ポジショニングとサイジング)sublayout()にのみ使用する必要があります。通常、その前にオブジェクトを作成する必要があります。通常、これはコンストラクターで発生します。メソッドの前半をコンストラクターに移動すると、この問題が修正されます。Fieldsublayout

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 に答える