Home > other >  Combobox action get's called when programmatically clearing selection
Combobox action get's called when programmatically clearing selection

Time:03-07

I am using this piece of code to try and remove the item that get's selected from a combobox and I want to do something further with it, but the problem is that the value selected should be removed from the list. The following is what I am using to fill the dropdown

            unpickedRoles = FXCollections.observableArrayList();
            rollenDropdown.setItems(unpickedRoles);
            
            unpickedRoles.addAll(Rol.DIRECTIE, Rol.MANAGER, Rol.MVOC, Rol.STAKEHOLDER);   
    @FXML
    private void selectRol(ActionEvent event) {
        Rol selected = rollenDropdown.getSelectionModel().getSelectedItem();
        if (selected != null) {
            rollenDropdown.getSelectionModel().clearSelection();
            rollenDropdown.getItems().remove(selected);
        }
    }

Now whenever the code get's called when a selection is made apart from the first one, the code seems to get's recalled internally by the rollenDropdown.getSelectionModel().clearSelection(); function, how could I remove the selection without the javafx action getting recalled? And how come this only happens when not selecting the first one?

EDIT: It probably has something to do with an item getting deselected thus recalling the method

EDIT 2: Adding a null check does not help

Kind regards Jasper

CodePudding user response:

According to How to remove selected elements from a ComboBox I had to use Platform.runLater() in order to make sure that the property change is dealt with before doing anything with the selection. This is the working code:

    @FXML
    private void selectRol(ActionEvent event) {
        Rol selected = rollenDropdown.getSelectionModel().getSelectedItem();
        if (selected != null) {
            Platform.runLater(() -> {
                rollenDropdown.setValue(null);
                rollenDropdown.getItems().remove(selected);
            });
        }
    }

CodePudding user response:

If you are concerned about the unspecified time at which Platform.runLater executes the action, you can try the below approach.

This approach is effectively using the AnimationTimer to run the desired actions at the end of the current pulse.

Considering its possible performance issues (mentioned in the doc),I would prefer to use Platform.runLater only in multi threading situations.

@FXML
private void selectRol(ActionEvent event) {
    Rol selected = rollenDropdown.getSelectionModel().getSelectedItem();
    if (selected != null) {
        doEndOfPulse(() -> {
            rollenDropdown.setValue(null);
            rollenDropdown.getItems().remove(selected);
        });
    }
}

/**
 * Executes the provided runnable at the end of the current pulse.
 *
 * @param runnable runnable to execute
 */
public static void doEndOfPulse(final Runnable runnable) {
    new AnimationTimer() {

        AtomicInteger count = new AtomicInteger(0);

        @Override
        public void handle(final long now) {
            if (count.getAndIncrement() ==0) {
                runnable.run();
                stop();
            }
        }
    }.start();
}
  • Related