summerNight
summerNight

Reputation: 1496

Trigger ComboBox selection event for the same item

I have a ComboBox that has the following implementation as shown in code below. The problem I am facing is that I can only trigger ChangeListener one time for a selected item. I would like to trigger as many times as I click on the same item.

int lastGridRowPos = 4;
ObservableList<String> options = FXCollections.observableArrayList(
                "IdentityFile",
                "LocalForward",
                "RemoteForward",
                "ForwardAgent",
                "ForwardX11"
        );

ComboBox propertyBox = new ComboBox(options);
propertyBox.valueProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue ov, String t, String t1) {
        System.out.println("SELECTED=" + t1);
        int rowCounter = getRowCount(grid);
        grid.add(new Label(t1), 0, rowCounter + 1);
        TextField field = newTextFieldWithIdPrompt(t1.toUpperCase(), "");
        grid.add(field, 1, rowCounter + 1);
        propertyBox.getSelectionModel().clearSelection();
    }
});

I was trying to clear the selection so that I can click on the same item again (hoping that the combo box sees a change in item) by using propertyBox.getSelectionModel().clearSelection(); but its not working.

Upvotes: 2

Views: 1133

Answers (1)

DVarga
DVarga

Reputation: 21799

I am almost sure that a simpler solution exists, but you could try to use the setCellFactory and add an EventFilter to the returned ListCell instance:

propertyBox.setCellFactory(param -> {
    final ListCell<String> cell = new ListCell<String>() {
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (!empty)
                setText(item);
        }
    };
    cell.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
        propertyBox.setValue(null);
        propertyBox.getSelectionModel().select(cell.getItem());

        e.consume();
    });
    return cell;
});

These ListCells will capture mouse pressed events on the list items inside the ComboBox and consumes these event. Then they manually set the valueProperty of the ComboBox to null (to erase the selection) then it sets this property to the item what the ListCell is displaying.

Then in the ChangeListener of the valueProperty you just need to check for nulls:

propertyBox.valueProperty().addListener((obs, oldVal, newVal) -> {
    if (newVal != null)
        System.out.println("Selected: " + newVal);
});

Additional note:

I don't know your exact use case but maybe a Menu with MenuItems is a better solution .

Upvotes: 3

Related Questions