我正在屏幕上创建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);
}
}
});
谢谢并恭祝安康。
最佳答案
解
尝试使用此代码。它允许您创建任意数量的复选框。选中一个时,侦听器将取消选中所有其他。
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()
方法。对于CheckboxField
,这是在选中或取消选中该字段时发生的。这可能是由于用户选中/取消选中该字段,或者是因为您的代码调用了setChecked(boolean)
。这行:if(context != FieldChangeListener.PROGRAMMATIC){ //It means manually clicked by User
是什么使
fieldChanged()
中的代码可以确定是否由于用户更改了字段或由于您的代码调用了setChecked()
而发生此调用。不幸的是,您已经在setChecked()
语句的所有分支中放置了对if
的调用,这导致用户事件和代码更改字段时都调用setChecked()
。在此代码中:
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()
的递归调用是导致堆栈溢出的原因。希望能有所帮助。