javalistviewjavafxcheckboxchangelistener

ListChangeListener, AddListener to ListView or Boolean Checkboxes in ListView


I have a java program I didn´t code that I am reversing/updating in order to add some much needed functionality.

This program generates two ListViews, list1:NameEntry & list2:GroupEntry based on some csv files found in /input.

NameEntry contains a list of user names with respective checkboxes. GroupEntry contains a long list of user roles with its checkboxes.

My current task was to add a 'Select All Roles' checkbox to the GUI that sets all the GroupEntry role items to 'true'. This was accomplished successfully.

My issue is adding an onChanged() listener to either the ListView or the individual checkbox items in order to disable the 'Set All Roles' toggle in the case that one or more of the roles is manually unchecked.

@FXML
  public void setAllRoles()
  {
    ObservableList<GroupEntry> groups = this.list2.getItems();
    if (this.allRoles) {
      this.allRoles = false;
      for (GroupEntry item : groups) {
      item.setSelected(new SimpleBooleanProperty(false));
      this.list2.refresh();
      }
    } else {
      this.allRoles = true;
      for (GroupEntry item : groups) {
      item.setSelected(new SimpleBooleanProperty(true));
      item.addListener(new ListChangeListener<GroupEntry>() {
           public abstract onChanged(ObservableValue<? extends GroupEntry> ov,
             Boolean old_val, Boolean new_val) {
                 //System.out.println(item.isSelected());
                 allRoles = false;
             }
      });
      }
      this.list2.refresh();
    }
  }

When trying to compile the controller .class file I receive the below error:

invalid method declaration; return type required
           public abstract onChanged(ObservableValue<? extends GroupEntry> ov,
                           ^

I´ve also tried without the abstract but compiler returns the same error.

This is all javafx. Does anyone have any idea what the issue could be or have any clear examples/guidelines? I´ve read countless documentation pages but cannot seem to wrap my head around this simple error. I am fairly new to Java but not coding.

Many thanks ahead of time!


Solution

  • After much investigation and trial&error the code below now functions correctly while providing the correct visual feedback, using checkbox.setIndeterminate() and implementing 'current threshhold', 'max threshhold' integer variables paired with 'item.isSelected().getValue()' conditions to trigger checkbox state. Surely there are cleaner ways to implement but this worked for me. Fixed as so:

    public void setAllRoles()
    {
    thrshld = 0;
    ObservableList<GroupEntry> groups = this.list2.getItems();
    for (GroupEntry item : groups) {
      thrshld--;
    }
    thrshldMax = thrshld;
    
    if (this.allRoles) {
      this.allRoles = false;
      for (GroupEntry item : groups) {
        item.setSelected(new SimpleBooleanProperty(false));
        item.isSelected().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> ov,
              Boolean old_val, Boolean new_val) {
                BooleanProperty thatCB = item.isSelected();
                if (thatCB.getValue() == true) {
                  checkbox2.setIndeterminate(true);
                  thrshld++; // = thrshld + 1;
                } else {
                  thrshld--; // = thrshld - 1;
                } 
                if (thrshld == thrshldMax) {
                  checkbox2.setIndeterminate(false);
                  checkbox2.setSelected(false);
                }
                if (thrshld == 0) {
                  checkbox2.setIndeterminate(false);
                  checkbox2.setSelected(true);
                }
                //status.setText("state: " +thatCB.getValue()+ "\r\nthrshld: " +thrshld+ "Max: " +thrshldMax);
              }
        });
      }
      this.list2.refresh();
    } else {
      this.allRoles = true;
      thrshld = 0;
      for (GroupEntry item : groups) {
        item.setSelected(new SimpleBooleanProperty(true));
        item.isSelected().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> ov,
              Boolean old_val, Boolean new_val) {
                BooleanProperty thisCB = item.isSelected();
                if (thisCB.getValue() == true) {
                  thrshld++; // = thrshld + 1;
                  if (thrshld == 0) {
                    checkbox2.setIndeterminate(false);
                    checkbox2.setSelected(true);
                  }
                } else {
                  checkbox2.setIndeterminate(true);
                  thrshld--; // = thrshld - 1;
                  if (thrshld == thrshldMax) {
                    checkbox2.setIndeterminate(false);
                    checkbox2.setSelected(false);
                  }
                }
                //status.setText("state: " +thisCB.getValue()+ "\r\nthrshld: " +thrshld+ "Max: " +thrshldMax);
              }
        });
      }
      this.list2.refresh();
     }
    }
    

    Thanks to those who gave their 2 cents! Take care stackoverflow!