Reputation: 5723
I've set multiple selection mode to my TableView and I want multiple rows to be selected with Lclick
, not Ctrl + Lclick
. Is there a simple way to do this.
I tried table.setOnMouseClicked()
with null implementation but it doesn't prevents target row to be selected and previously selected row to be unselected, either setOnMousePressed()
or setOnMouseReleased()
.
I really don't want to re-implement TableView.TableViewSelectionModel
. There should be a layer between click and calling TableView.TableViewSelectionModel.clearAndSelect()
UPD I've just found a few questions with the similar problem but not exactly the same. Those guys wanted to drag and select multiple, when I want to select one-by-one, but without keyboard.
Upvotes: 2
Views: 2810
Reputation: 209225
In general, changing behavior for JavaFX UI controls is difficult (or impossible), and generally I'd recommend just accepting the default behaviors (even if they're not what your users might really want).
In this case, I think you can make this work by adding an event filter to the table rows, implementing the desired selection behavior and consuming the event (to prevent the default behavior getting invoked).
Here's an example:
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MultipleSelectTable extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Person> table = new TableView<>();
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setRowFactory(tv -> {
TableRow<Person> row = new TableRow<>();
row.addEventFilter(MouseEvent.MOUSE_PRESSED, e-> {
if (! row.isEmpty() && e.getClickCount() == 1) {
Person person = row.getItem() ;
if (table.getSelectionModel().getSelectedItems().contains(person)) {
int index = row.getIndex() ;
table.getSelectionModel().clearSelection(index);
} else {
table.getSelectionModel().select(person);
}
e.consume();
}
});
return row ;
});
table.getColumns().add(column("First Name", Person::firstNameProperty));
table.getColumns().add(column("Last Name", Person::lastNameProperty));
table.getColumns().add(column("Email", Person::emailProperty));
table.getItems().addAll(
new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]")
);
BorderPane root = new BorderPane(table);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private static <S,T> TableColumn<S,T> column(String text, Function<S,ObservableValue<T>> property) {
TableColumn<S,T> col = new TableColumn<>(text);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setPrefWidth(200);
return col ;
}
private static class Person {
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
private final StringProperty email = new SimpleStringProperty();
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
}
public final StringProperty firstNameProperty() {
return this.firstName;
}
public final java.lang.String getFirstName() {
return this.firstNameProperty().get();
}
public final void setFirstName(final java.lang.String firstName) {
this.firstNameProperty().set(firstName);
}
public final StringProperty lastNameProperty() {
return this.lastName;
}
public final java.lang.String getLastName() {
return this.lastNameProperty().get();
}
public final void setLastName(final java.lang.String lastName) {
this.lastNameProperty().set(lastName);
}
public final StringProperty emailProperty() {
return this.email;
}
public final java.lang.String getEmail() {
return this.emailProperty().get();
}
public final void setEmail(final java.lang.String email) {
this.emailProperty().set(email);
}
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 4