JavaFX - How disable CheckboxListCell in ListView?

I have no idea how can I make disable checkboxes in checklistview. CheckListView is from the controlsfx. I am newbie.

Task object, which has to be wrapped into a checkbox list cell.

  public class Task {



  private final ReadOnlyStringWrapper name;

  private final ReadOnlyIntegerWrapper blockId;

  private final SimpleBooleanProperty isSelected;


  private final boolean isFound;

  public Task(String name, boolean isSelected, int blockId) {
    this.name = new ReadOnlyStringWrapper(name);
    this.isSelected = new SimpleBooleanProperty(isSelected);
    this.blockId = new ReadOnlyIntegerWrapper(blockId);
    this.isFound = isSelected;
  }

  public boolean isSelected() {
    return isSelected.get();
  }

  public void setSelected(boolean selected) {
    this.isSelected.set(selected);
  }

  public SimpleBooleanProperty selectedProperty() {
    return isSelected;
  }

  public String getName() {
    return name.get();
  }

  public ReadOnlyStringProperty nameProperty() {
    return name.getReadOnlyProperty();
  }

  public int getBlockId() {
    return blockId.get();
  }

  public ReadOnlyIntegerProperty blockIdProperty() {
    return blockId.getReadOnlyProperty();
  }

  @Override
  public String toString() {
    return getName();
  }

  public boolean isFound() {
    return isFound;
  }

ListView

  List<Task> tasksOfSection = domainModel.getTasks();
  final ObservableList<Task> tasks = FXCollections.observableArrayList(tasksOfSection);
  final CheckListView<Task> checkListView = new CheckListView<>(tasks);

  Callback<ListView<Task>, ListCell<Task>> wrappedCellFactory = checkListView.getCellFactory();

  checkListView.setCellFactory(listView -> {
      CheckBoxListCell<Task> cell =  new CheckBoxListCell<>();

      if (wrappedCellFactory != null) {
        cell = (CheckBoxListCell<Task>) wrappedCellFactory.call(listView);            
      }
      cell.setSelectedStateCallback((Task item) -> item.selectedProperty());

      // This throw null pointer exception.
      cell.setDisable(!cell.getItem().isFound());

      cell.itemProperty().addListener(new ChangeListener<Task>(){
        @Override
        public void changed(ObservableValue<? extends Task> observable, Task oldValue, Task newValue) {             
          // I cannot modify here the checkbox cell...           
        }

      });

      return cell;
    }
  );

So I call the cell.setDisable() method on the CheckboxListCell, but I have a problem, the cell's item (a task object) always null, when I call it with the getItem() method.

Yes, I have tried to override the updateItem function(), but when I scrolling in the listview, then the checkboxes were setted to disable, the updateItem is listen every event, I think this. So this was useless. I want to disable the checkbox which isFound's value false, because I want to prevent that the User click on it. But the user should see the full list.

What do you think, what can I do?

Thanks for the help.

Upvotes: 1

Views: 1577

Answers (2)

Thank you :)

A few hours ago finally I solved with this implementation:

checkListView.setCellFactory((ListView<Task> item) -> {
  final CheckBoxListCell<Task> cell =  new CheckBoxListCell<>((Task t) -> t.selectedProperty());
  cell.itemProperty().addListener((obs, s, s1) -> {
    cell.disableProperty().unbind();
    if (s1!=null) {
      Task tm = tasks.stream().filter(t -> t.getIdentifier() == s1.getIdentifier()).findFirst().orElse(null);
      if (tm != null)
        cell.disableProperty().bind(tm.disabledProperty());
    }
  });
  return cell;
});

But your solution looks more clear.

Upvotes: 0

oszd93
oszd93

Reputation: 193

  • First you have to rewrite your cell-construction into a single statement so it is effectively final within the function.
  • Then you have to check if the cell's item is null (since the CheckListView also creates empty cells to fill up the list).
  • In addition you have to wrap the NullpointerCheck and setDisable-Methodcall into a Platform.runLater since it has to be executed on the JavaFX-Thread (and the getItem-Methodcall always returns null within the cellfactory).

So your CellFactory should look like this:

checkListView.setCellFactory(listView -> {
        CheckBoxListCell<Task> cell = wrappedCellFactory != null ? (CheckBoxListCell<Task>) wrappedCellFactory.call(listView) : new CheckBoxListCell<>();
        cell.setSelectedStateCallback((Task item) -> item.selectedProperty());

        Platform.runLater(() -> {
            if (cell.getItem() != null)
                cell.setDisable(!cell.getItem().isFound());
        });

        cell.itemProperty().addListener(new ChangeListener<Task>() {
            @Override
            public void changed(ObservableValue<? extends Task> observable, Task oldValue, Task newValue) {
                // I cannot modify here the checkbox cell...
            }

        });

        return cell;
    });

Upvotes: 2

Related Questions