I\'m using a ListView control in a JavaFX application. It is set for MULTIPLE selection mode. I know as a user, I can Ctrl-Click an item to deselect it, but this is not intu
Changing the behavior of controls in JavaFX is pretty difficult - there are really no hooks currently in the API into the behavior classes.
The following seems to work, by registering an event filter with the cells in the list, implementing the selection behavior directly, and consuming the event.
It feels a bit fragile though (what if a future release decided to implement the default behavior on mouse clicked, instead of mouse pressed, for example; or perhaps better, what if a future release decided to add additional functionality handled by mouse events). So use this solution with a bit of a "buyer beware" notice attached.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MultipleSelectionModel;
import javafx.scene.control.SelectionMode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class DeselectableList extends Application {
@Override
public void start(Stage primaryStage) {
ListView<String> list = new ListView<>();
MultipleSelectionModel<String> selectionModel = list.getSelectionModel();
selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
for (int i=1; i<=20; i++) {
list.getItems().addAll("Item "+i);
}
list.setCellFactory(lv -> {
ListCell<String> cell = new ListCell<>();
cell.textProperty().bind(cell.itemProperty());
cell.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
list.requestFocus();
if (! cell.isEmpty()) {
int index = cell.getIndex();
if (selectionModel.getSelectedIndices().contains(index)) {
selectionModel.clearSelection(index);
} else {
selectionModel.select(index);
}
event.consume();
}
});
return cell ;
});
BorderPane root = new BorderPane(list);
Scene scene = new Scene(root, 150, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Obviously you know your users better than I, but I might prefer just to have a nice tooltip on the ListView
explaining to them how to use it...