0

我在我的屏幕中创建 2-3 个复选框字段并将它们添加到垂直字段管理器中。这里的想法是在单击另一个复选框时禁用其他复选框。但它给了我stackoverflow错误。我在这里发布我的代码...

final CheckboxField[] checkBoxField = new CheckboxField[2];
checkBoxField[0] = cashCardCheckboxField;
checkBoxField[1] = creditDebitCardCheckboxField;

checkBoxField[0].setChangeListener(new FieldChangeListener() {
    public void fieldChanged(Field field, int context) {

        if(context != FieldChangeListener.PROGRAMMATIC){  //It means manually clicked by User
            if(checkBoxField[0].getChecked()){
                checkBoxField[0].setChecked(false);
            }else{
                checkBoxField[0].setChecked(true);
                //Please wait Screen starts
                // call here a user defined function to populate the drop down list
                //Please wait Screen ends
            }
        }else{
            checkBoxField[0].setChecked(false);
        }
    }
});

checkBoxField[1].setChangeListener(new FieldChangeListener() {
    public void fieldChanged(Field field, int context) {

        if(context != FieldChangeListener.PROGRAMMATIC){  //It means manually clicked by User

            if(checkBoxField[1].getChecked()){
                checkBoxField[1].setChecked(false);
            }else{
                checkBoxField[1].setChecked(true);
                //Please wait Screen starts
                // call here a user defined function to populate the drop down list
                //Please wait Screen ends
            }

        }else{
            checkBoxField[1].setChecked(false);
        }

    }
});

谢谢并恭祝安康。

4

1 回答 1

1

解决方案

尝试使用此代码。它允许您创建任意数量的复选框。当一个被选中时,监听器将取消选中所有其他的。

public class CheckBoxScreen extends MainScreen {

   private CheckboxField checkBoxField[];

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

      checkBoxField = new CheckboxField[3];
      checkBoxField[0] = new CheckboxField("one", true);  // checked by default
      checkBoxField[1] = new CheckboxField("two", false);
      checkBoxField[2] = new CheckboxField("three", false);

      FieldChangeListener listener = new CheckboxListener();

      for (int i = 0; i < checkBoxField.length; i++) {
         checkBoxField[i].setChangeListener(listener);
         add(checkBoxField[i]);
      }
   }

   private class CheckboxListener implements FieldChangeListener {

      public void fieldChanged(Field field, int context) {

         if (context != FieldChangeListener.PROGRAMMATIC) {
            // user modified this field
            CheckboxField checkbox = (CheckboxField)field;   
            if (checkbox.getChecked()) {              
               // uncheck the other checkboxes
               for (int i = 0; i < checkBoxField.length; i++) {
                  if (checkBoxField[i] != checkbox && checkBoxField[i].getChecked()) {
                     checkBoxField[i].setChecked(false);
                  }
               }
            }
         } else {  
            // nothing more to do here ... this time, fieldChanged() is being
            //  called as a result of calling setChecked() in the code.
         }
      }      
   }
}

为什么您的代码会导致堆栈溢出

fieldChanged()只要字段的属性被修改,该方法就会被调用。对于 a CheckboxField,当该字段被选中或未选中时会发生这种情况。这可能是因为用户选中/取消选中该字段,或者因为您的代码调用setChecked(boolean). 这一行:

if(context != FieldChangeListener.PROGRAMMATIC){  //It means manually clicked by User

是什么允许内部代码fieldChanged()确定发生此调用是因为用户更改了字段,还是因为setChecked()被您的代码调用。不幸的是,您已经在语句setChecked()的所有分支中调用了 to,这导致在用户事件和代码更改字段时都被调用。 ifsetChecked()

在这段代码中:

    checkBoxField[0].setChangeListener(new FieldChangeListener() {
        public void fieldChanged(Field field, int context) {

            if(context != FieldChangeListener.PROGRAMMATIC){  //It means manually clicked by User
                if(checkBoxField[0].getChecked()){
                    checkBoxField[0].setChecked(false);
                }else{
                    checkBoxField[0].setChecked(true);
                    //Please wait Screen starts
                    // call here a user defined function to populate the drop down list
                    //Please wait Screen ends
                }
            }else{
                checkBoxField[0].setChecked(false);
            }
        }
    });

checkBoxField[0].setChecked(false);导致问题的是最后一行 ( )。else在调用语句setChecked()“手动单击”分支后到达该分支。if再次调用后,您已经以编程setChecked(false)方式修改了该字段。这将导致再次被回调。然后再次。然后再次。这个循环永远不会停止,直到程序堆栈满了,你的应用程序崩溃了。fieldChanged()

所以,如果你看到我的代码,你会注意到我没有在语句setChecked()程序分支中调用。if代码中的另一个问题是,当检查复选框0时,您没有正确的逻辑到取消选中的复选框1。但是,这只是一个功能性错误。递归调用fieldChanged()是导致堆栈溢出的原因。

希望有帮助。

于 2013-09-25T01:48:41.307 回答