Question

I am implementing a simple app, where in the registration page user can select news categories. Requirements are below

  1. All the categories are the CheckBoxField's. User have to select at least one category.
  2. Select all CheckBox will allow to select all/deselect all categories CheckBox.
  3. If user manually selects all checkbox fields then "Select All" checkbox must be selected.

Approaches: I have created the categories checkbox in a loop.

for(int i=0;i<interests.length;i++){
    allFields[i] = new ColorCheckBoxField(interests[i], false, checkBoxStyle | USE_ALL_WIDTH);
    allFields[i].setCookie(i+"");
    allFields[i].setFont(bodyFont);
    allFields[i].setChangeListener(new FieldChangeListener() {
         public void fieldChanged(Field field, int context) {
            ColorCheckBoxField tempChoice = (ColorCheckBoxField)field;
            int index =Integer.parseInt(tempChoice.getCookie().toString().trim());
            //set the selection
            if(tempChoice.getChecked()){
                parent.selectInterest(index);
            }

            boolean flag = true;
            int[] intrests = parent.getSelectedInterest();
            for (int i = 0; i < intrests.length; i++) {                     
                if(intrests[i]==0){
                    flag = false;
                }
            }

            if(flag==true){
                selectAll.setChecked(flag); // select all is Checkbox object
            }else{
                selectAll.setChecked(false);
            }
        }
    });
    vfm.add(allFields[i]);
} 

My selectAll checkbox logic is

        selectAll = new ColorCheckBoxField("Select All", false, checkBoxStyle | USE_ALL_WIDTH);
        selectAll.setChangeListener(new FieldChangeListener() {         
            public void fieldChanged(Field field, int context) {
                ColorCheckBoxField temp = (ColorCheckBoxField) field;
                //if (context == FieldChangeListener.PROGRAMMATIC ) {
                    checkAll(temp.getChecked()); // it loops through all checkbox and set them checked
                //}
            }
        }); 

        innerHfm.add(selectAll);

I understand the problem, its due to infinite loop. I have used "FieldChangeListener.PROGRAMMATIC" but that wont help because i want the field listener to work for both pragmatically and manually. I don't have any option left to fix. Any hack will help me?

Was it helpful?

Solution

That's correct that you have to use FieldChangeListener.PROGRAMMATIC. But you have to use it with interest checkboxes instead of using it for selectAll checkbox.

Please add one defensive check to FieldChangeListener for interest checkboxes:

if ( nonProgrammaticChange(context) ) {
   ColorCheckBoxField tempChoice = (ColorCheckBoxField)field;
   int index = Integer.parseInt(tempChoice.getCookie().toString().trim());
   ...
}

Where nonProgrammaticChange is:

private boolean nonProgrammaticChange (int context) {
    return (context & FieldChangeListener.PROGRAMMATIC) != FieldChangeListener.PROGRAMMATIC;
}

I see bug in your code - you don't clear interest in parent if checkbox is unchecked.

Minor improvements as for me - use Vector where you'll store indexes of selected checkboxes. This will allow to replace this code:

boolean flag = true;
int[] intrests = parent.getSelectedInterest();
for ( int i = 0; i < intrests.length; i++ ) {                     
     if( intrests[i] == 0 ) {
          flag = false;
     }
}

To this code:

selectedInterestIndexes.size() == interests.length

And probably this will give you less iteration in other places.

As well I would work more on removal of duplicates and code readability.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top